Qt之QCheckBox


簡述

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。

更多參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM