2013-09-24 52 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); 
} 
相关问题