2009-09-28 25 views
6

我翻看相關的問題,找不到任何能解決我正在談論的問題,所以讓我來描述一下。在Qt中,如何使用Q_OBJECT插槽和具有多重繼承的信號?

我有一個類,讓我們說foo需要有自己的插槽和信號,但也需要從QXmlDefaultHandler繼承(聽起來很奇怪,但是當我嘗試使用QHttp直接讀取網站時遇到這種情況一個QBuffer)。

class foo: public QXmlDefaultHandler, public QObject 
{ 
    public: 
     foo(); 
     ~foo(); 

     Q_OBJECT 
    public slots: 
     void bar(); 
} 

這段代碼,如果伴隨着一個cpp連接欄到其他地方的信號,將不會編譯。你會得到有關QObject的一些成員不是QXmlDefaultHandler成員的錯誤。另外,你不能移動Q_OBJECT,否則你會因爲不執行某些事情而出現vtable錯誤(繼續嘗試!)。

請參閱我的答案(非常簡單)修復。如果我認爲你比我更好地解釋它,我會接受你的投票。

編輯:對於你C++和Qt獸醫,請發表一個答案,如果你能更好地解釋它。我花了很多時間查看這些信息,所以如果你能比我做得更好,請幫助其他人。

回答

12

documentation for moc指出,在多重繼承的情況下,提供的QObject類應首先出現

如果使用多重繼承, 商務部假定第一繼承 類是QObject的一個子類。另外, 請確保只有第一個繼承的 類是QObject。

// correct 
class SomeClass : public QObject, public OtherClass 
{ 
    ... 
}; 

QObject的虛擬繼承不支持 。

2
class foo: public QObject, public QXmlDefaultHandler 
{ 
    public: 
     foo(); 
     ~foo(); 
    Q_OBJECT 
    public slots: 
     void bar(); 
} 

就像聽起來那麼簡單,如果你不把第一個QObject放在繼承列表中,這個任務是不可能的。這是Qt的元對象系統的限制。如果你不這樣做,編譯器將嘗試應用QObject的一些成員作爲QXmlDefaultHandler的一部分。