选中QCheckBox时启用QCheckBox

时间:2016-04-13 12:10:31

标签: c++ qt

我是Qt和GUI编程的新手,当参数列表不匹配时,我不确定将信号连接到插槽的最佳方法。我有一个使用Qt Designer制作的设置对话框,它包含一系列QCheckBoxes和QLineEdits,默认情况下禁用QLineEdits。我想在选中旁边的QCheckBox时启用QLineEdit。

起初我想把QCheckBox :: stateChanged信号连接到QLineEdits :: setEnabled插槽,但是当我看到时我发现它们有不同的参数类型,所以这显然不会起作用:

connect(checkBox1, SIGNAL(stateChanged(int)), lineEdit1, SLOT(setEnabled(bool)));
connect(checkBox2, SIGNAL(stateChanged(int)), lineEdit2, SLOT(setEnabled(bool)));
connect(checkBox3, SIGNAL(stateChanged(int)), lineEdit3, SLOT(setEnabled(bool)));

接下来我想在对话框类中创建setLineEditEnabled(int)函数,以便在选中QCheckBox时启用相应的QLineEdit:

connect(checkBox1, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEditEnabled(int)));
connect(checkBox2, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEditEnabled(int)));
connect(checkBox3, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEditEnabled(int)));

当我开始编写setLineEditEnabled()函数时,我意识到无法知道哪个QCheckBox发送了信号,所以我不知道应该启用哪个QLineEdit:

void SettingsDialog::setLineEditEnabled(int checkState)
{
    ????->setEnabled(checkState == Qt::Checked);
}

我能想到的唯一解决方案就是在对话框类中有一系列函数,每个复选框都有一个函数:

connect(checkBox1, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEdit1Enabled(int)));
connect(checkBox2, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEdit2Enabled(int)));
connect(checkBox3, SIGNAL(stateChanged(int)), settingsDialog, SLOT(setLineEdit3Enabled(int)));

void SettingsDialog::setLineEdit1Enabled(int checkState)
{
    lineEdit1->setEnabled(checkState == Qt::Checked);
}

void SettingsDialog::setLineEdit2Enabled(int checkState)
{
    lineEdit2->setEnabled(checkState == Qt::Checked);
}

void SettingsDialog::setLineEdit3Enabled(int checkState)
{
    lineEdit3->setEnabled(checkState == Qt::Checked);
}

然而,这似乎有些混乱(实际上有七个QCheckBox-QLineEdit对,所以我需要七个功能),我觉得我错过了一些可以让这更容易的东西。如果我知道哪个对象发送了信号,我可以用一个函数来完成它,这将更加整洁。

有没有办法获得从插槽函数发送信号的对象?

如果没有办法获得信号对象,是否有更好的解决方案,在对话框类中没有多个函数来启用QLineEdits?

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

在这种情况下,您可以使用QCheckBox::toggled(bool)信号代替stateChanged(int)

connect(checkBox1, SIGNAL(toggled(bool)), lineEdit1, SLOT(setEnabled(bool)));
connect(checkBox2, SIGNAL(toggled(bool)), lineEdit2, SLOT(setEnabled(bool)));
connect(checkBox3, SIGNAL(toggled(bool)), lineEdit3, SLOT(setEnabled(bool)));

但是,在插槽中,您可以获取发送信号的QObject调用sender()方法。见QObject::sender()

答案 1 :(得分:0)

另一种选择是使用 QSignalMapper

// Set up a map, just for convenience.
std::map<QCheckBox*, QLineEdit*> widgetMap;
widgetMap.emplace(checkBox1, lineEdit1);
widgetMap.emplace(checkBox2, lineEdit2);
widgetMap.emplace(checkBox3, lineEdit3);

QSignalMapper signalMapper;
connect(signalMapper, SIGNAL(mapped(QWidget*)), SLOT(singleSlotHandlingThemAll(QWidget*)));

connect(checkBox1, SIGNAL(statusChanged(int)), signalMapper, SLOT(map()));
connect(checkBox2, SIGNAL(statusChanged(int)), signalMapper, SLOT(map()));
connect(checkBox3, SIGNAL(statusChanged(int)), signalMapper, SLOT(map()));

signalMapper->setMapping(checkBox1, checkBox1);
signalMapper->setMapping(checkBox2, checkBox2);
signalMapper->setMapping(checkBox3, checkBox3);

这里是singleSlotHandlingThemAll()实施:

void singleSlotHandlingThemAll(QWidget* widget)
{
    // Provided widget is one of the check-boxes.
    QCheckBox* checkBox = static_cast<QCheckBox8>(widget);

    QLineEdit* relatedLineEdit = widgetMap[checkBox];
    relatedLineEdit->setEnabled(checkBox->isChecked());
}