Reputation: 199
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. 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. I want to enable a QLineEdit when the QCheckBox next to it is checked.
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:
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:
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:
void SettingsDialog::setLineEditEnabled(int checkState)
{
????->setEnabled(checkState == Qt::Checked);
}
The only solution I can think is to think of is to have a a 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. 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?
Thanks for your help.
Upvotes: 0
Views: 6696
Reputation: 2210
Another option would be using a 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:
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());
}
Upvotes: 0
Reputation: 2602
In this case you can use the QCheckBox::toggled(bool)
signal instead of 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. See QObject::sender()
Upvotes: 3