QObject Multiple Inheritance

Solution 1:

Unfortunately inheriting QObject twice will cause problems in moc.

From http://qt-project.org:

If you are using multiple inheritance, moc assumes that the first inherited class is a subclass of QObject. Also, be sure that only the first inherited class is a QObject.

I would suggest using something more like the delegate pattern, or recreate with a HasA not a IsA relationship.

Solution 2:

Qt allows multiple inheritance if the base class inherits privately from QObject.

Example:

class Base: private QObject {
   Q_OBJECT
   /*Can use signals and slots like any other QObject-derived class*/
};

class Derived1: public Base {
   /*Cannot use signals/slots because it does not "see" that Base inherits from QObject*/
};

class Derived2: public QWidget, public Base {
   Q_OBJECT
   /*Can use signals/slots plus has all the functionality of QWidget and Base*/
};

Of course, private inheritance is a different animal altogether and may not give you the solution you really need. What I use it for is when I can get away with using signals/slots only in the base class. When I really do need QObject behavior in a derived class, I inherit from QObject specifically for just that class.

Solution 3:

Why using inheritance, why not composition? For example, you can rewrite your case the next way:

class IMyWidgetSignals : public QObject
{
    Q_OBJECT
signals:
    void iconChanged(QIcon);
    void titleChanged(QString);
};

//------------------------------------------------------------------------------

class IMyWidget {
public:
    IMyWidget () {}
    // virtual functions:
    // ...
    
    IMyWidgetSignals _signals;
};


//------------------------------------------------------------------------------

class Widget1: public QWidget, public IMyWidget
{
public:
    using QWidget::QWidget;
}
//------------------------------------------------------------------------------

int main(...)
{
    
    Widget1 w1;
    w1.show();

    QObject::connect(&w1._signals, &IMyWidgetSignals::iconChanged, [] (const auto &icon) { 
        // ... do smth with icon
    });
}