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?
-
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 acceptintvalues, if signal passes an integer.Nevermind. Was confused because of parameter differences :)
(e.g. Int + String wont work)Is your class
DelayedEditSpinBoxpure virtual or do you actually create instances? -
@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 acceptintvalues, if signal passes an integer.Nevermind. Was confused because of parameter differences :)
(e.g. Int + String wont work)Is your class
DelayedEditSpinBoxpure virtual or do you actually create instances? -
@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
DelayedEditSpinBoxhave multiple constructors?
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,
- What's the implementation of
-
@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
-
@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
-
Qt Version? Compiler Version?
In general it should work with MSVC
https://wiki.qt.io/New_Signal_Slot_Syntax -
Qt Version? Compiler Version?
In general it should work with MSVC
https://wiki.qt.io/New_Signal_Slot_Syntax -
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(); } -
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(); }