2013-09-24 79 views
2

我建立一套QCheckBox的動態基於像這樣一些用戶輸入:引發一個信號當QCheckBox被經過

QWidget *wid = new QWidget(); 
QVBoxLayout *layout = new QVBoxLayout(); 
for(int i=0; i<NumberModes; i++) 
{ 
    int k = Amplitudes(i,0); 
    int m = Amplitudes(i,1); 

    QString ks = QString::number(k); 
    QString ms = QString::number(m); 
    QString position = QString::number(i); 
    QString mode = "A"+ks+ms; 

    QCheckBox *check = new QCheckBox(mode); 
    connect(check, SIGNAL(toggled(bool)), &mapper, SLOT(map())); 
    connect(check, SIGNAL(toggled(bool)), &SelectModes, SLOT(map())); 

    mapper.setMapping(check,position); 
    SelectModes.setMapping(check,mode); 
    layout->addWidget(check); 
    updateGeometry(); 
} 


wid->setLayout(layout); 
ui->scrollArea->setWidget(wid); 

的QSignalMapper然後連接到另一個類執行一些計算:

connect(&SelectModes, SIGNAL(mapped(QString)), this, SIGNAL(CheckBoxClicked2(QString))); 
connect(this, SIGNAL(CheckBoxClicked2(QString)), &Supress2, SLOT(ListenSelectedModes(QString))); 
connect(&mapper, SIGNAL(mapped(QString)), this, SIGNAL(CheckBoxClicked(QString))); 
connect(this, SIGNAL(CheckBoxClicked(QString)), &Suppress, SLOT(ListenSelectedModes(QString))); 

我需要的是這些類只在QCheckBox被選中時纔會接收信號;這意味着如果您檢查一次,然後取消檢查它不應發出或接收信號。不知道最好的方法是什麼。 任何想法?

+1

你能澄清哪個事件應該發出信號?當checckboxes被選中時,而不是當他們沒有被選中時?一種方法應該是對複選框進行子類化。添加一個專用插槽,發出用戶定義的信號,該信號僅在適當的時候被命名。 – user2672165

+0

對,只有在檢查時纔會發出信號。所以如果我有3個QcheckBox:C1,C2和C3;並且用戶檢查C1和C2,但是然後取消選中C2,只發出C1的信號。不知道我是否有任何意義:) – user1981855

+0

然後只有我知道(QSignalMapper不是很熟悉)的方法是,每當它們中的任何一個改變狀態時都會通過所有複選框。然後你可以在子類複選框中有一個公共的功能,如果你選中的話,你可以發出它。你也可以給自己的對象添加一個信號,它可以發出一個只包含選中對象的列表。 – user2672165

回答

1

user2672165給出的建議非常好!

如果你想只監視檢查事件,但沒有取消選中事件,一個辦法是子類QCheckBox小部件,使其發出只有當複選框被選中(如checkBoxChecked

然後特​​定信號您將信號映射器連接到自定義信號checkBoxChecked,而不是標準的toggle(bool)信號。

通過這種方式,只有在複選框被選中時,纔會調用與信號映射器關聯的槽,而不是在未選中時調用。

下面是一個簡單的例子

#include <QApplication> 
#include <QtGui> 
#include <QVBoxLayout> 
#include <QSignalMapper> 
#include <QCheckBox> 
#include <QDebug> 

class CheckableCheckBox : public QCheckBox { 
    Q_OBJECT 

public: 
    CheckableCheckBox(const QString &text, QWidget *parent = 0) 
     : QCheckBox(text, parent) 
    { 
     connect(this, SIGNAL(toggled(bool)), 
      this, SLOT(verifyCheck(bool))); 
    } 

signals: 
    void checkBoxChecked(); 

public slots: 
    void verifyCheck(bool checked) { 
     if (checked) 
      emit checkBoxChecked(); 
    } 
}; 

class Test : public QWidget { 
    Q_OBJECT 
public: 
    Test(QWidget *parent = 0) : QWidget(parent) { 
     QSignalMapper *mapper = new QSignalMapper(); 

     QVBoxLayout *layout = new QVBoxLayout(); 
     for (int i = 0; i < 10; i++) { 
      QString mode = "A" + QString::number(i); 
      CheckableCheckBox *check = new CheckableCheckBox(mode); 
      connect(check, SIGNAL(checkBoxChecked()), 
       mapper, SLOT(map())); 

      mapper->setMapping(check, QString::number(i)); 
      layout->addWidget(check); 
      setLayout(layout); 
     } 
     connect(mapper, SIGNAL(mapped(QString)), 
      this, SLOT(CheckBoxClicked(QString))); 
    } 

public slots: 
    void CheckBoxClicked(const QString &mapping) { 
     qWarning() << "Checkbox:" << mapping << " is checked"; 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 

    Test *wid = new Test(); 
    wid->show(); 

    return a.exec(); 
} 

#include "main.moc" 

編輯:

如果要監視在檢查狀態的改變,然後通知到代碼中的地位的一些其它部分的複選框(這可能是你想要的),你可以做這樣的事情......你甚至不需要QSignalMapper ...

我哈哈已經實施了測試方法testMonitorCheckStatus來展示我的意思。請注意,您需要typedef QList<bool> CheckBoxStatusList;(至少據我所知)使用QList作爲插槽和信號的參數。

編輯#2: 複選框的數量設置爲創建對象

希望這有助於

#include <QApplication> 
#include <QtGui> 
#include <QVBoxLayout> 
#include <QSignalMapper> 
#include <QCheckBox> 
#include <QList> 
#include <QDebug> 

typedef QList<bool> CheckBoxStatusList; 

class Test : public QWidget { 
    Q_OBJECT 
public: 
    Test(int totalCheckboxes, QWidget *parent = 0) : QWidget(parent) 
    { 
     QVBoxLayout *layout = new QVBoxLayout(); 
     for (int i = 0; i < totalCheckboxes; i++) { 
      QString mode = "A" + QString::number(i); 
      QCheckBox *checkBox = new QCheckBox(mode); 
      connect(checkBox, SIGNAL(toggled(bool)), 
       this, SLOT(monitorCheckStatus())); 
      m_checkBoxList.append(checkBox); 
      layout->addWidget(checkBox); 
     } 
     setLayout(layout); 

     connect(this, SIGNAL(checkBoxStatusChanged(CheckBoxStatusList)), 
      this, SLOT(testMonitorCheckStatus(CheckBoxStatusList))); 
    } 

public slots: 
    void monitorCheckStatus() { 
     CheckBoxStatusList checkBoxStatus; 
     for (int i = 0; i < m_checkBoxList.count(); ++i) 
      checkBoxStatus.append(m_checkBoxList.at(i)->isChecked()); 
     emit checkBoxStatusChanged(checkBoxStatus); 
    } 

    void testMonitorCheckStatus(const CheckBoxStatusList &checkBoxStatus) { 
     for (int i = 0; i < checkBoxStatus.count(); ++i) 
      qWarning() << "Checkbox:" << i << " is" << (checkBoxStatus.at(i) ? "checked" : "unchecked"); 
     qWarning(" "); 
    } 

signals: 
    void checkBoxStatusChanged(const CheckBoxStatusList &checkBoxStatus); 

private: 
    QList<QCheckBox *> m_checkBoxList; 
}; 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 

    Test *wid = new Test(10); 
    wid->show(); 

    return a.exec(); 
} 

#include "main.moc" 
+0

這是一個很好的例子,謝謝!還有,感謝user2672165。 雖然我有一個問題,如果用戶檢查CheckBox然後取消選中,會發生什麼情況?信號發出的第一次檢查,所以即使它沒有選中它仍然傳遞給類,至少據我實現這個(真棒)代碼後我可以告訴。 – user1981855

+0

我意識到我已經使用了錯誤的函數'verifyUncheck',而不是'verifyCheck',它更有意義!我完全不瞭解你的問題。但基本上SignalMapper只獲取檢查事件。我不知道這是不是你的意思... –

+0

也許我沒有提供足夠的上下文。假設有2個QCheckBox創建了C1和C2。用戶然後檢查兩者,但然後取消檢查C1。在程序的後面,有些計算需要只檢查C1的信息,但是SignalMapper已經檢查了,因爲C1在某個時刻被檢查。我可能會錯過一些東西,雖然... – user1981855

4

用C++ 11它是可行的簡單,沒有QSignalMapper。這是一個工作示例。

#include <QWidget> 
#include <QCheckBox> 
#include <QVBoxLayout> 

class QCheckBox; 

class Widget : public QWidget 
{ 
    Q_OBJECT 

public: 
    explicit Widget(QWidget *parent = 0); 

signals: 
    void checkBoxChecked(QCheckBox *checkBox); 
}; 


Widget::Widget(QWidget *parent) : 
    QWidget(parent) 
{ 
    QVBoxLayout *layout = new QVBoxLayout; 

    for (int i = 0; i < 10; ++i) { 
     QCheckBox *checkBox = new QCheckBox("CheckBox " + QString::number(i + 1)); 

     connect(checkBox, &QCheckBox::toggled, [=](bool checked) { 
      if (checked) 
       emit checkBoxChecked(checkBox); 
     }); 

     layout->addWidget(checkBox); 
    } 

    setLayout(layout); 
} 
相關問題