简体   繁体   English

选中QCheckBox时启用QCheckBox

[英]Enabling QCheckBox when QCheckBox is checked

I'm new to Qt and GUI programming and am unsure of the best way to connect a signal to to a slot when the parameter list doesn't match. 我是Qt和GUI编程的新手,不确定参数列表不匹配时将信号连接到插槽的最佳方法。 I have a settings dialog box made with Qt Designer and it contains a series of QCheckBoxes and QLineEdits, with the QLineEdits disabled by default. 我有一个使用Qt Designer创建的设置对话框,它包含一系列QCheckBoxes和QLineEdits,默认情况下禁用QLineEdits。 I want to enable a QLineEdit when the QCheckBox next to it is checked. 我要在选中旁边的QCheckBox时启用QLineEdit。

At first I thought to connect the QCheckBox::stateChanged signal to the QLineEdits::setEnabled slot, but when I looked I found they had different parameter types so this obviously won't work: 起初我想将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)));

Next I thought to create setLineEditEnabled(int) function in the dialog box class to enable the appropriate QLineEdit when a QCheckBox is checked: 接下来,我想在对话框类中创建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)));

When I came to write the setLineEditEnabled() function I realised there's no way to know which QCheckBox sent the signal, so I don't know which QLineEdit should be enabled: 当我开始编写setLineEditEnabled()函数时,我意识到无法知道哪个QCheckBox发送了信号,所以我不知道应该启用哪个QLineEdit:

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

The only solution I can think is to think of is to have aa series of functions in the dialog class, with one for each checkbox: 我能想到的唯一解决方案是在对话框类中具有一系列功能,每个复选框都有一个功能:

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);
}

However, that seems a bit messy (there are actually seven QCheckBox-QLineEdit pairs so I'd need seven functions), and I feel I'm missing something that would make this easier. 但是,这似乎有点混乱(实际上有七个QCheckBox-QLineEdit对,所以我需要七个功能),而且我觉得我缺少使它更容易的东西。 If I knew which object sent the signal I could do it with a single function, which would be tidier. 如果我知道哪个对象发送了信号,则可以使用一个简单的函数完成该任务。

Is there a way get the object that sent the signal from the slot function? 有没有办法从插槽功能中获取发送信号的对象?

If there's no way to get the signalling object, is there a better solution to this that doesn't involve having multiple functions in the dialog class for enabling the QLineEdits? 如果无法获取信号对象,是否有更好的解决方案,而在对话框类中不包含用于启用QLineEdits的多个功能?

Thanks for your help. 谢谢你的帮助。

In this case you can use the QCheckBox::toggled(bool) signal instead of stateChanged(int) . 在这种情况下,可以使用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)));

However, inside a slot, you can get the QObject that sent the signal calling the sender() method. 但是,在插槽内,您可以获取发送信号的QObject ,该信号调用sender()方法。 See QObject::sender() 参见QObject :: sender()

Another option would be using a QSignalMapper : 另一种选择是使用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);

And here's the singleSlotHandlingThemAll() implementation: 这是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());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM