Lets say I have a main window with a slider and a widget inside that window with a method called setValue(int)
. I'd like to call this method every time the value of the slider has changed.
Is there any practical difference between the two following ways of achieving it:
void MainWindow::on_slider_valueChanged(int value)
{
ui->widget->setValue(value);
}
// somewhere in constructor
connect(ui->slider, SIGNAL(valueChanged(int)), ui->widget, SLOT(setValue(int)));
For me the first approach looks better, because it possibly avoids some overhead related to signals and slots mechanism and also, allows me to process the value
before sending it to widget
, if there's a need for it.
Are there any scenarios where the second solution is better?
Both approaches use signal-slot connections. In the first case, the connect
call is made by QMetaObject::connectSlotsByName()
called from setupUi
. In the second case, you explicitly call connect
yourself.
Also, the first approach is unnecessary in Qt5 when using C++11. You can modify the value in a lambda:
QObject::connect(ui->slider, &QAbstractSlider::valueChanged,
[this](int val){ ui->widget->setValue(val*2); });
To protect from deletion of ui->widget
, you should use a QPointer
:
class MyWindow : public QMainWindow {
QPointer<QAbstractSlider> m_widget;
...
public:
MyWindow(QWidget * parent = 0) : QMainWindow(parent) {
...
setupUi(this);
m_widget = ui->widget;
QObject::connect(ui->slider, &QAbstractSlider::valueChanged,
[this](int val)
{
if (!m_widget.isNull()) m_widget->setValue(val*2);
});
The overhead of signal-slot connections is quantified in this answer.
Signal/slot advantages:
Signal/slot drawbacks:
More details are available here
The main difference, in your example, of using a signal instead of a direct call, is to allow more than one listener.
If you directly call your widget setValue()
, then only that one widget will receive the C++ signal.
If you use a Qt signal, now any other object can connect to receive the event whenever it occurs.
If you do not foresee any other object to ever want to receive the value by signal, I would not bother with such. A direct call is definitively a lot faster (between 3 and 6 CPU instructions instead of dealing with strings to find receivers!), but as Paranaix mentioned, in a GUI it may not be much of an issue (although in this case it could become a problem on older computers if you send all those signals while moving the sliderbar.)
I prefer the second method, since it happened that I forgot to delete the "auto-connect-slots" when the UI-element was removed, causing dead code. AFAIK it is the same "behind the scene" (look at the auto-generated qt-files).
When you would like to modify the value I would prefer following method:
connect(ui->slider, SIGNAL(valueChanged(int)), this, SLOT(myOwnSlot(int)));
void MainWindow::myOwnSlot(int value) {
/** do stuff */
ui->widget->setValue(value);
}
Greetz
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With