【问题标题】:QObject Multiple InheritanceQObject 多重继承
【发布时间】:2012-01-24 14:32:39
【问题描述】:

我正在尝试在 C++/Qt 的类中使用混合来提供一大堆具有通用界面的小部件。接口是这样定义的,如果它被定义为其他小部件类的基类,那么小部件本身就会有这些信号:

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 继承自QWidgetSignalInterface,两者都继承自QObject。这会导致任何问题吗?

我们知道,如果QObject 类是纯虚拟的(事实并非如此),这个问题就可以轻松解决。

一个可能的解决方案是:

class Interface: public QWidget {
Q_OBJECT

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

class Widget1: public Interface {

}

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

【问题讨论】:

标签: c++ qt user-interface


【解决方案1】:

很遗憾,两次继承QObject 会导致moc 出现问题。

来自http://qt-project.org

如果您使用多重继承,moc 假定第一个 继承类是QObject的子类。此外,请确保只有 第一个继承的类是 QObject

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

【讨论】:

  • 请注意,对于 Qt5,此规则保持不变:doc.qt.io/qt-5/…(您提供了 Qt4 文档的链接)
  • (在 2011 年问及回答这个问题时,Qt5 还不存在)
【解决方案2】:

如果基类私有地从 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 继承,专门用于该类。

【讨论】:

  • 使用 Qt5.9,此解决方案在编译 moc 生成的文件时出错:'static_cast': ambiguous conversions from 'QObject *' to 'myClass *'
【解决方案3】:

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-29
  • 2011-09-24
相关资源
最近更新 更多