2

我正在根据一些用户输入动态创建一组 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 时接收信号;这意味着如果您检查一次,然后取消检查,则不应发出或接收任何信号。不确定最好的方法是什么。有任何想法吗?

4

2 回答 2

5

使用 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);
}
于 2013-09-24T21:35:17.593 回答
2

user2672165给出的建议非常好!

如果您只想监视 check 事件而不监视 uncheck 事件,一种方法是子类化 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"
于 2013-09-24T20:35:38.080 回答