Solved Multiple inheritance and signals/slots
-
I understood multiple inheritance is ok, as long as only one of the base classes is derived from QObject and this class is inherited first. But I can't get it to work.
My code looks like this:
class DelayedEditSpinBox : public QSpinBox { Q_OBJECT protected slots: void onValueChanged(); ... }; DelayedEditSpinBox::DelayedEditSpinBox( QWidget* parent ) : QSpinBox( parent ) { connect( this, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) ); } class ParameterWidget { public: ParameterWidget( Parameter* parameter ); virtual ~ParameterWidget(); ... }; class IntParameterWidget : public DelayedEditSpinBox, public ParameterWidget { Q_OBJECT public: explicit IntParameterWidget( QWidget* parent, Parameter* parameter ); ... };
The issue is that in the DelayedEditSpinBox::onValueChanged() slot never receives the DelayedEditSpinBox::valueChanged( int ) signal when DelayedEditSpinBox is derived from IntParameterWidget . But it does if DelayedEditSpinBox is 'standalone'.
Everything works fine if IntParameterWidget is derived from QSpinBox instead of DelayedEditSpinBox and I connect to the SpinBox::valueChanged( int ) signal.
Any ideas?
-
@AndyBrice said in Multiple inheritance and signals/slots:
connect( this, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );
Idk if just a typo, but the slot has to acceptint
values, if signal passes an integer.Nevermind. Was confused because of parameter differences :)
(e.g. Int + String wont work)Is your class
DelayedEditSpinBox
pure virtual or do you actually create instances? -
@Pl45m4 A slot can ignore the parameters in a signal. I do it all the time.
-
@AndyBrice said in Multiple inheritance and signals/slots:
@Pl45m4 A slot can ignore the parameters in a signal. I do it all the time.
That's indeed the case, however, I would suggest using the "new" Qt5 Signal Slot Syntax
You can even specify the signal/slot to use, if to use it from the parent class or not
DelayedEditSpinBox::DelayedEditSpinBox( QWidget* parent ) : QSpinBox( parent ) { connect( this, QOverLoad<int>::of(&QSpinBox::valueChanged), this, &DelayedEditSpinBox::onValueChanged); }
in case you shadow signals or slots
-
- What's the implementation of
IntParameterWidget::IntParameterWidget
? - Does
DelayedEditSpinBox
have multiple constructors?
- What's the implementation of
-
What's the implementation of IntParameterWidget::IntParameterWidget?
IntParameterWidget::IntParameterWidget( QWidget* parent, Parameter* parameter ) : DelayedEditSpinBox( parent ), ParameterWidget( parameter ) { ... }
It connects to a signal from DelayedEditSpinBox. But that signal is never emitted.
Does DelayedEditSpinBox have multiple constructors?
No,
-
@J-Hilk I will try that. Thanks!
-
@J-Hilk This syntax doesn't seem to work on MSVC. :0(
-
Qt Version? Compiler Version?
In general it should work with MSVC
https://wiki.qt.io/New_Signal_Slot_Syntax -
@Pl45m4 MSVC 2015 on Windows 7.
-
I tested the below with Qt 5.12.5, MinGW 7.3.0 64bit on Win 10 and it's working
#include <QSpinBox> #include <QApplication> class Parameter; class DelayedEditSpinBox : public QSpinBox { public: explicit DelayedEditSpinBox( QWidget* parent =nullptr ) : QSpinBox( parent ) { connect( this,static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &DelayedEditSpinBox::onValueChanged ); } void onValueChanged(){ qDebug("onValueChanged"); } }; class ParameterWidget { public: ParameterWidget( Parameter* parameter =nullptr ){} virtual ~ParameterWidget()=default; }; class IntParameterWidget : public DelayedEditSpinBox, public ParameterWidget { public: explicit IntParameterWidget( QWidget* parent=nullptr, Parameter* parameter=nullptr ) :DelayedEditSpinBox(parent),ParameterWidget(parameter) {} }; int main(int argc, char *argv[]) { QApplication a(argc, argv); IntParameterWidget w; w.show(); return a.exec(); }
-
@VRonin I will try it, thanks. It might be a while, because I am going to be away from my dev PC.
-
It turns out that I was later calling QObject::disconnect() on IntParameterWidget, which also disconnected signals in the base classes, including the QComboBox valueChanged( int ) signal. So it isn't a Qt bug/issue. Just my stupidity. Oops.