簡述
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()開啟三態模式。
QCheckBox *pCheckBox = new QCheckBox(this);
m_pLabel = new QLabel(this);
m_pLabel->setText("Click CheckBox...");
pCheckBox->setText(QString::fromLocal8Bit("三態復選框"));
// 開啟三態模式
pCheckBox->setTristate();
// 連接信號槽
connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onStateChanged(int)));
槽函數,判斷當前復選框狀態,其中包括:選中(Qt::Checked)、半選(Qt::PartiallyChecked)、未選中(Qt::Unchecked)。
void MainWindow::onStateChanged(int state)
{
if (state == Qt::Checked) // "選中"
{
m_pLabel->setText("Checked");
}
else if(state == Qt::PartiallyChecked) // "半選"
{
m_pLabel->setText("PartiallyChecked");
}
else // 未選中 - Qt::Unchecked
{
m_pLabel->setText("Unchecked");
}
}
QSS
復選框樣式。
QCheckBox{ spacing: 5px; color: white; }
QCheckBox::indicator { width: 17px; height: 17px; }
QCheckBox::indicator:enabled:unchecked { image: url(:/Images/checkBox); }
QCheckBox::indicator:enabled:unchecked:hover { image: url(:/Images/checkBoxHover); }
QCheckBox::indicator:enabled:unchecked:pressed { image: url(:/Images/checkBoxPressed); }
QCheckBox::indicator:enabled:checked { image: url(:/Images/checkBoxChecked); }
QCheckBox::indicator:enabled:checked:hover { image: url(:/Images/checkBoxCheckedHover); }
QCheckBox::indicator:enabled:checked:pressed { image: url(:/Images/checkBoxCheckedPressed); }
QCheckBox::indicator:enabled:indeterminate { image: url(:/Images/checkBoxIndeterminate); }
QCheckBox::indicator:enabled:indeterminate:hover { image: url(:/Images/checkBoxIndeterminateHover); }
QCheckBox::indicator:enabled:indeterminate:pressed { image: url(:/Images/checkBoxIndeterminatePressed); }
連接stateChanged()信號和槽函數,當用戶點擊復選框時,狀態發生改變就會調用槽函數。
那么,如果我們不是手動在界面上點擊,如何執行槽函數呢?
這時,有些人就會說這很簡單啊,看connect就清楚了,直接發射stateChanged()信號或直接調用槽函數:
emit pCheckBox->stateChanged(Qt::PartiallyChecked);
onStateChanged(Qt::PartiallyChecked);
這當然可以。這里我想說的是除了這種方式外,還有木有其它方式呢?我們追朔到QCheckBox的基類QAbstractButton,它里面有一系列的信號和函數,我們可以嘗試一下。
經過試驗,我們歸結了兩類,分別是可觸發和不可觸發槽函數的:
- 不可觸發槽函數:
emit pCheckBox->clicked(true);
emit pCheckBox->toggled(true);
emit pCheckBox->pressed();
emit pCheckBox->released();
- 可觸發槽函數:
pCheckBox->animateClick();
pCheckBox->click();
pCheckBox->toggle();
pCheckBox->setChecked(true);
pCheckBox->setCheckState(Qt::PartiallyChecked); // QCheckBox自身接口
也就是說,通過調用這些信號或函數,我們可以很容易判定其是否可以觸發stateChanged()信號,從而調用槽函數onStateChanged()。
開關效果
我們來實現一個iphone中常見的開關效果 - 多選。
效果
源碼
構建復選框QCheckBox,然后將它們添加至按鈕組QButtonGroup中。
QHBoxLayout *pLayout = new QHBoxLayout();
m_pButtonGroup = new QButtonGroup(this);
// 設置不互斥
m_pButtonGroup->setExclusive(false);
for (int i = 0; i < 3; ++i)
{
QCheckBox *pCheckBox = new QCheckBox(this);
// 設置文本
pCheckBox->setText(QString::fromLocal8Bit("切換%1").arg(i + 1));
pLayout->addWidget(pCheckBox);
m_pButtonGroup->addButton(pCheckBox);
}
pLayout->setSpacing(10);
pLayout->setContentsMargins(10, 10, 10, 10);
setLayout(pLayout);
// 連接信號槽
connect(m_pButtonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(onButtonClicked(QAbstractButton*)));
槽函數,用來判斷當前點擊的按鈕,以及獲取按鈕組各個按鈕的選中狀態。
void MainWindow::onButtonClicked(QAbstractButton *button)
{
// 當前點擊的按鈕
qDebug() << QString("Clicked Button : %1").arg(button->text());
// 遍歷按鈕,獲取選中狀態
QList<QAbstractButton*> list = m_pButtonGroup->buttons();
foreach (QAbstractButton *pCheckBox, list)
{
QString strStatus = pCheckBox->isChecked() ? "Checked" : "Unchecked";
qDebug() << QString("Button : %1 is %2").arg(pCheckBox->text()).arg(strStatus);
}
}
QSS
復選框樣式
QCheckBox{ spacing: 2px; color: white; }
QCheckBox::indicator { width: 45px; height: 30px; }
QCheckBox::indicator:unchecked { image: url(:/Images/switchOff); }
QCheckBox::indicator:unchecked:hover { image: url(:/Images/switchOffHover); }
QCheckBox::indicator:unchecked:pressed { image: url(:/Images/switchOffPressed); }
QCheckBox::indicator:checked { image: url(:/Images/switchOn); }
QCheckBox::indicator:checked:hover { image: url(:/Images/switchOnHover); }
QCheckBox::indicator:checked:pressed { image: url(:/Images/switchOnPressed); }
上面,我們通過調用QButtonGroup的setExclusive(false)來設置按鈕組中的復選框不互斥(可以多選)。
如上,我們使用了QButtonGroup,僅僅為了演示復選框實現單選功能(只需設置setExclusive(true)打開互斥即可)。即使這樣,如之前所言 - 強烈建議使用眾所周知的約定。所以,如果要實現單選功能,建議選擇QRadioButton。