QObject多重继承

时间:2011-12-20 16:29:21

标签: c++ qt user-interface

我正在尝试在C ++ / Qt的类中使用mix来提供一大堆具有通用接口的小部件。接口以这样的方式定义,以便如果将其定义为其他窗口小部件类的基类,则窗口小部件本身将具有这些信号。即参考下文。

class SignalInterface: public QObject {
    Q_OBJECT

    public:
    SignalInterface();
    virtual ~SignalInterface();

    signals:
    void iconChanged(QIcon);
    void titleChanged(QString);
}

class Widget1: public SignalInterface, QWidget{

    public:
    Widget1()
    virtual ~Widget1()

    // The Widget Should Inherit the signals
}

看看类层次结构问题变得明显,我偶然发现了多重继承中的可怕钻石,其中Widget1继承自QWidget和SignalInterface,两者都继承自QObject。这会引起任何问题吗?

我们知道,如果QObject类是纯虚拟的,那么这个问题就很容易解决(事实并非如此)。

可能的解决方案是

class Interface: public QWidget {
Q_OBJECT

signals:
void IconChanged(QIcon);
void titleChanged(QString);
}

class Widget1: public Interface {

}

这里的问题是我已经有很多代码继承自QWidget,并且很难将其破解。还有其他方法吗?

3 个答案:

答案 0 :(得分:47)

不幸的是,继承QObject两次会导致moc出现问题。

来自http://qt-project.org

  

如果您使用多重继承, moc假设第一个   继承类是QObject的子类。另外,请确保仅限于   第一个继承的类是QObject

我建议使用更像委托模式的东西,或者使用HasA而不是IsA关系重新创建。

答案 1 :(得分:6)

如果基类从QObject继承私有,Qt允许多重继承。

示例:

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*/
};

当然,私人继承完全是一种不同的动物,可能无法为您提供您真正需要的解决方案。我用它的原因是我只能在基类中使用信号/插槽。当我在派生类中确实需要QObject行为时,我专门为该类继承QObject

答案 2 :(得分:0)

为什么使用继承,为什么不使用组合? 例如,您可以按以下方式重写您的案例:

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
    });
}