簡述
QCheckBox繼承自QAbstractButton,它提供了一個帶文本標簽的復選框。
QCheckBox(復選框)和QRadioButton(單選框)都是選項按鈕。這是因為它們都可以在開(選中)或者關(未選中)之間切換。區別是對用戶選擇的限制:單選框定義了“多選一”的選擇,而復選框提供的是“多選多”的選擇。
盡管在技術上可以通過復選框來實現單選框的行為,反之亦然,但還是強烈建議使用眾所周知的約定。
詳細描述
QButtonGroup可以用來在視覺上把許多復選框組織在一起。
只要復選框被選中或者清除,都會發射一個stateChanged()信號。如果想在復選框狀態改變的時候觸發一個行為,請連接這個信號,可以使用 isChecked()來查詢復選框是否被選中。
除了常用的選中和未選中兩個狀態,QCheckBox還可選地提供了第三種狀態(半選)來表明“沒有變化”。當需要給用戶一個選中或者未選中復選框的選擇時,這是很有用的。如果需要第三種狀態,可以通過setTristate()來使它生效,並使用checkState()來查詢當前的切換狀態。
和QPushButton一樣,復選框可以顯示文本或者圖標。文本可以通過構造函數或者setText()來設置,圖標可以通過setIcon()來設置。
QCheckBox *checkbox = new QCheckBox("C&ase sensitive", this);
這個例子中,快捷鍵為Alt+a,詳情請參閱QShortcut文檔。要顯示一個實際的符號,使用“&&”。
重要的繼承函數:text()、setText()、pixmap()、setPixmap()、accel()、setAccel()、isToggleButton()、setDown()、isDown()、isOn()、checkState()、 autoRepeat()、isExclusiveToggle()、group()、setAutoRepeat()、toggle()、pressed()、released()、clicked()、toggled()、checkState()、stateChanged()。
共有函數
Qt::CheckState checkState() const
返回復選框的選中狀態。如果不需要三態的支持,可以使用QAbstractButton::isChecked(),它返回一個布爾值。
bool isTristate() const
復選框是否為一個三態復選框。
默認的是false,也就是說復選框只有兩個狀態。
void setCheckState(Qt::CheckState state)
設置復選框的選中狀態。如果不需要三態的支持,可以使用QAbstractButton:setChecked(),它接受一個布爾值。
void setTristate(bool y = true)
設置復選框為一個三態復選框。
信號
void stateChanged(int state)
當復選框狀態發生改變,這個信號就會被發射。即:用戶選中或者取消選中。
示例
三態復選框
下面,我們實現一個三態復選框,並監聽狀態變化。
效果
源碼
構造一個復選框QCheckBox,然后使用setTristate()開啟三態模式。
1 QCheckBox *pCheckBox = new QCheckBox(this); 2 m_pLabel = new QLabel(this); 3
4 m_pLabel->setText("Click CheckBox..."); 5 pCheckBox->setText(QString::fromLocal8Bit("三態復選框")); 6
7 // 開啟三態模式
8 pCheckBox->setTristate(); 9
10 // 連接信號槽
11 connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onStateChanged(int)));
槽函數,判斷當前復選框狀態,其中包括:選中(Qt::Checked)、半選(Qt::PartiallyChecked)、未選中(Qt::Unchecked)。
1 void MainWindow::onStateChanged(int state) 2 { 3 if (state == Qt::Checked) // "選中"
4 { 5 m_pLabel->setText("Checked"); 6 } 7 else if(state == Qt::PartiallyChecked) // "半選"
8 { 9 m_pLabel->setText("PartiallyChecked"); 10 } 11 else // 未選中 - Qt::Unchecked
12 { 13 m_pLabel->setText("Unchecked"); 14 } 15 }
QSS
復選框樣式。
1 QCheckBox{ 2 spacing: 5px; 3 color: white; 4 } 5 QCheckBox::indicator { 6 width: 17px; 7 height: 17px; 8 } 9 QCheckBox::indicator:enabled:unchecked { 10 image: url(:/Images/checkBox); 11 } 12 QCheckBox::indicator:enabled:unchecked:hover { 13 image: url(:/Images/checkBoxHover); 14 } 15 QCheckBox::indicator:enabled:unchecked:pressed { 16 image: url(:/Images/checkBoxPressed); 17 } 18 QCheckBox::indicator:enabled:checked { 19 image: url(:/Images/checkBoxChecked); 20 } 21 QCheckBox::indicator:enabled:checked:hover { 22 image: url(:/Images/checkBoxCheckedHover); 23 } 24 QCheckBox::indicator:enabled:checked:pressed { 25 image: url(:/Images/checkBoxCheckedPressed); 26 } 27 QCheckBox::indicator:enabled:indeterminate { 28 image: url(:/Images/checkBoxIndeterminate); 29 } 30 QCheckBox::indicator:enabled:indeterminate:hover { 31 image: url(:/Images/checkBoxIndeterminateHover); 32 } 33 QCheckBox::indicator:enabled:indeterminate:pressed { 34 image: url(:/Images/checkBoxIndeterminatePressed); 35 }
連接stateChanged()信號和槽函數,當用戶點擊復選框時,狀態發生改變就會調用槽函數。
那么,如果我們不是手動在界面上點擊,如何執行槽函數呢?
這時,有些人就會說這很簡單啊,看connect就清楚了,直接發射stateChanged()信號或直接調用槽函數:
1 emit pCheckBox->stateChanged(Qt::PartiallyChecked); 2 onStateChanged(Qt::PartiallyChecked);
這當然可以。這里我想說的是除了這種方式外,還有木有其它方式呢?我們追朔到QCheckBox的基類QAbstractButton,它里面有一系列的信號和函數,我們可以嘗試一下。
經過試驗,我們歸結了兩類,分別是可觸發和不可觸發槽函數的:
不可觸發槽函數:
1 emit pCheckBox->clicked(true); 2 emit pCheckBox->toggled(true); 3 emit pCheckBox->pressed(); 4 emit pCheckBox->released();
可觸發槽函數:
1 pCheckBox->animateClick(); 2 pCheckBox->click(); 3 pCheckBox->toggle(); 4 pCheckBox->setChecked(true); 5 pCheckBox->setCheckState(Qt::PartiallyChecked); // QCheckBox自身接口
也就是說,通過調用這些信號或函數,我們可以很容易判定其是否可以觸發stateChanged()信號,從而調用槽函數onStateChanged()。
開關效果
我們來實現一個iphone中常見的開關效果 - 多選。
效果
源碼
構建復選框QCheckBox,然后將它們添加至按鈕組QButtonGroup中。
1 QHBoxLayout *pLayout = new QHBoxLayout(); 2 m_pButtonGroup = new QButtonGroup(this); 3
4 // 設置不互斥
5 m_pButtonGroup->setExclusive(false); 6 for (int i = 0; i < 3; ++i) 7 { 8 QCheckBox *pCheckBox = new QCheckBox(this); 9
10 // 設置文本
11 pCheckBox->setText(QString::fromLocal8Bit("切換%1").arg(i + 1)); 12
13 pLayout->addWidget(pCheckBox); 14 m_pButtonGroup->addButton(pCheckBox); 15 } 16 pLayout->setSpacing(10); 17 pLayout->setContentsMargins(10, 10, 10, 10); 18
19 setLayout(pLayout); 20
21 // 連接信號槽
22 connect(m_pButtonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(onButtonClicked(QAbstractButton*)));
槽函數,用來判斷當前點擊的按鈕,以及獲取按鈕組各個按鈕的選中狀態。
1 void MainWindow::onButtonClicked(QAbstractButton *button) 2 { 3 // 當前點擊的按鈕
4 qDebug() << QString("Clicked Button : %1").arg(button->text()); 5
6 // 遍歷按鈕,獲取選中狀態
7 QList<QAbstractButton*> list = m_pButtonGroup->buttons(); 8 foreach (QAbstractButton *pCheckBox, list) 9 { 10 QString strStatus = pCheckBox->isChecked() ? "Checked" : "Unchecked"; 11 qDebug() << QString("Button : %1 is %2").arg(pCheckBox->text()).arg(strStatus); 12 } 13 }
QSS
復選框樣式
1 QCheckBox{ 2 spacing: 2px; 3 color: white; 4 } 5 QCheckBox::indicator { 6 width: 45px; 7 height: 30px; 8 } 9 QCheckBox::indicator:unchecked { 10 image: url(:/Images/switchOff); 11 } 12 QCheckBox::indicator:unchecked:hover { 13 image: url(:/Images/switchOffHover); 14 } 15 QCheckBox::indicator:unchecked:pressed { 16 image: url(:/Images/switchOffPressed); 17 } 18 QCheckBox::indicator:checked { 19 image: url(:/Images/switchOn); 20 } 21 QCheckBox::indicator:checked:hover { 22 image: url(:/Images/switchOnHover); 23 } 24 QCheckBox::indicator:checked:pressed { 25 image: url(:/Images/switchOnPressed); 26 }
上面,我們通過調用QButtonGroup的setExclusive(false)來設置按鈕組中的復選框不互斥(可以多選)。
如上,我們使用了QButtonGroup,僅僅為了演示復選框實現單選功能(只需設置setExclusive(true)打開互斥即可)。即使這樣,如之前所言 - 強烈建議使用眾所周知的約定。所以,如果要實現單選功能,建議選擇QRadioButton。