2011-12-25 63 views
1

我設計了一些建築是這樣的:連接(以不尋常的方式)的信號插槽

template<class Ui_Class> 
class Base_Dialog : virtual public QDialog, protected Ui_Class 
{ 

protected: 

    QDialog* caller_; 

public: 
    template<class Implementation> 
    Base_Dialog(Implementation*const & imp,QDialog *caller,QWidget* parent = nullptr); 

}; 

template<class Ui_Class> 
template<class Implementation> 
Base_Dialog<Ui_Class>::Base_Dialog(Implementation*const& imp,QDialog *caller,QWidget* parent): 
    QDialog(parent), 
    caller_(caller) 
{ 
    setupUi(imp); 
} 

我使用它像這樣:

class My_Class : public **Base_Dialog<Ui::My_Class>** 
{ 
    Q_OBJECT 


public slots: 
    void display_me() 
    {/*THIS IS NOT GETTING CONNECTED*/ 
     QMessageBox::warning(this,"Aha!","Aha!"); 
    } 

public: 
    explicit My_Class(QDialog* caller = nullptr,QWidget *parent = nullptr); 

}; 

Line_Counter::Line_Counter(QDialog* caller,QWidget *parent) : 
    Base_Dialog(this,caller,parent) 

{ 
    //setupUi(this);//THIS WORKS BUT I'D RATHER CALL IT FROM Base_Dialog 


} 

這上述構建是假設簡化並簡化從QDialog和Ui類繼承的方式。除了當我的課程中引入插槽和信號時,由於某些原因,基類沒有看到它們(插槽/信號),這是有效的。如果我在My_Class ctor中調用setupUi,一切正常,但我更願意在Base_Class中調用它。有沒有辦法做到這一點?

+0

你會得到一個錯誤:'沒有這樣的插槽BaseDialog :: displayMe()'? – cmannett85 2011-12-26 10:15:32

+0

moc可能無法正確處理模板。包含ui生成代碼的慣用方法是將Ui :: My_Class作爲成員。 – 2011-12-26 13:19:12

+0

@ cbamber85我收到的消息就像QDialog中沒有這樣的插槽。 – user336635 2011-12-26 13:52:33

回答

1

lineCounter的構造函數應該重命名爲My_Class,對嗎?

此行爲的原因是,在Base_Dialog的構造函數中從virtual const QMetaObject * metaObject() const返回的元對象是Base_Dialog的元對象,因爲在此階段它還不是My_Class實例的實例。 My_CLass覆蓋了這個虛擬方法(在Q_OBJECT宏中不可見),但只有在My_Class構造函數代碼開始執行之後 - 意味着Base_Dialog代碼完成後。信號和插槽在連接時內部使用元對象,所以看起來這樣不起作用。

總結 - 你不能這樣做,因爲Base_Dialog的構造函數不知道正在創建My_Class實例,因此不能訪問它的任何內容。

有時這個問題可以繞過使用CRTP,但在這種情況下,我不知道它是否適用。我寧願選擇按照Qt的方式 - 從My_Class構造函數調用setupUi。

+0

#j_kubik夠公平的。順便說一句,謝謝你,我試過crtp,但它不適合我。 – user336635 2011-12-27 14:26:05

+0

謝謝,我以爲我已經接受了。 – user336635 2011-12-29 17:16:33