2013-10-02 26 views
1

我必須創建2個自定義事件。 我跟着這個鏈接&使我的代碼: -
Is there a cleaner way to register Qt custom events?創建併發布定製的Qevent

是它創建&後&一些數據(QString的)傳遞到自定義事件的正確方法?

==============================================每庫巴奧伯sugession =============

編輯代碼:---

Mainwindow.h: -

UpdateEvent *myUpdateEvent ; 
ClearEvent *myClearEvent ; 

Mainwindow.c: - -

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 

    i =0; 
    myUpdateEvent = new UpdateEvent("hello"); 
    myClearEvent = new ClearEvent("bye"); 

    QCoreApplication::postEvent(this, myUpdateEvent); 
    QCoreApplication::postEvent(this, myClearEvent); 


} 

bool MainWindow::eventFilter(QObject *obj, QEvent *event) 
{ 

    qDebug() << "oo"; 
    if (UpdateEvent::is(event)) { 
     UpdateEvent *tempUpdateEvent = static_cast<UpdateEvent *>(event); 
     qDebug() << tempUpdateEvent->value(); 

    } 
    else if (ClearEvent::is(event)) { 
     ClearEvent *tempClearEvent = static_cast<ClearEvent *>(event); 
     qDebug() << tempClearEvent->value(); 

    } 

    return true; 

} 

event.h file: -

template <typename T> class StringEvent : public QEvent 
{ 
    QString m_str; 
public: 
    explicit StringEvent(const QString val) : QEvent(staticType()), m_str(val) 
    { 
    } 

    QString setvalue(QString val) 
    { 
     m_str = val; 
    } 

    QString value() const 
    { 
     return m_str; 
    } 

    static QEvent::Type staticType() 
    { 
     static int type = QEvent::registerEventType(); 
     return static_cast<QEvent::Type>(type); 

    } 

    static bool is(const QEvent * ev) 
    { 
     return ev->type() == staticType(); 
    } 
}; 

class UpdateEvent : public StringEvent<UpdateEvent> 
{ 
public: 
    explicit UpdateEvent(QString val): StringEvent(val) 
    { 

    } 

}; 

class ClearEvent : public StringEvent<ClearEvent> 
{ 
public: 
    explicit ClearEvent(QString val): StringEvent(val) 
    { 

    } 
}; 

爲什麼eventFilter沒有被觸發?而且我無法在postevent上看到調試消息?

回答

0

我只能評論你的事件實現的代碼味道,因爲目前還不清楚爲什麼你需要將事件發送到窗口中的編輯控件。後者是糟糕的設計。

你的事件類是不必要的複雜。您應該在施工期間設置事件內的所有值,然後應該通過只讀訪問器訪問它們。額外的事件類型似乎也是不必要的噱頭。

下面是我該怎麼做,使用一個元模型(我剛剛創造的一個名稱,也許有一個更好/現有的名稱?)。這解決了需要顯式派生類構造器注入,否則需要。

爲了便於理解,我已經將小組件類拆分爲小組件類。

// A type-identifier-generating wrapper for events 
template <typename D> class EventWrapper : public QEvent { 
public: 
    EventWrapper() : QEvent(staticType()) {} 
    static QEvent::Type staticType() { 
     static QEvent::Type type = static_cast<QEvent::Type>(registerEventType()); 
     return type; 
    } 
    static bool is(const QEvent * ev) { return ev->type() == staticType(); } 
    static D* cast(QEvent * ev) { return is(ev) ? static_cast<D*>(ev) : 0; } 
}; 

// The generic event metafactory for C++98 (doesn't need C++11) 
template <typename D, template <typename> class Carrier> class EventMF { 
    class EventFwd; 
    class Final; 
    class FinalWrapper : public EventWrapper<EventFwd>, public virtual Final {}; 
public: 
    // EventFwd is a class derived from Event. The EventWrapper's cast() 
    // will cast to a covariant return type - the derived class. That's OK. 
    typedef Carrier<FinalWrapper> Event; 
private: 
    class EventFwd : public Event {}; 
    class Final { 
     friend class FinalWrapper; 
     friend class Carrier<FinalWrapper>; 
    private: 
     Final() {} 
     Final(const Final &) {} 
    }; 
}; 

// A string carrier 
template <typename B> class StringData : public B { 
    QString m_str; 
public: 
    explicit StringData(const QString & str) : m_str(str) {} 
    QString value() const { return m_str; } 
}; 

// A string event metafactory 
template <typename D> class StringEventMF : public EventMF<D, StringData> {}; 

class Update : public EventMF<Update, StringData> {}; // using generic metafactory 
class Clear : public StringEventMF<Clear> {}; // using specific metafactory 
#if 0 
// This should fail at compile time as such derivation would produce classes with 
// duplicate event types. That's what the Final class was for in the matafactory. 
class Error : public Update::Event { Error() : Update::Event("") {} }; 
#endif 

int main(int, char**) 
{ 
    // Test that it works as expected. 
    Update::Event update("update"); 
    Clear::Event clear("clear"); 
    Q_ASSERT(Update::Event::staticType() != Clear::Event::staticType()); 
    Q_ASSERT(Update::Event::staticType() == Update::Event::cast(&update)->staticType()); 
    qDebug() << Update::Event::cast(&update)->value(); 
    Q_ASSERT(Update::Event::cast(&clear) == 0); 
    qDebug() << Clear::Event::cast(&clear)->value(); 
    Q_ASSERT(Clear::Event::cast(&update) == 0); 
} 

Metafactory::EventQEvent得出自定義事件類。 的類層次結構更新::事件看起來如下(從最低推導最派生類中去):

  • EventWrapper<EventMF<...>::EventFwd>EventMF<...>::Final(多重繼承)
  • EventMF<Update, StringData<Update>>::FinalWrapper
  • StringData<Update> = EventMF<Update, StringData<Update>>::Event

    EventMF<...>EventMF<Update, StringData<Update>的簡寫。

Update::Event update("update")構建一個自定義字符串攜帶事件實例,從最後調用上面列表中的第一個建設者的線。

由於EventMF<...>是一個僅在編譯時工作的元數據集,所以在運行時絕對不需要其實例存在。因此EventMF<...>::EventMF構造函數永遠不會被調用。您可以通過刪除構造函數(將其聲明爲C++ 98專用)來強制執行此不變量。

事件處理程序中使用看起來像:

+0

感謝..從這件事吸取線程很多C++的概念......最後一件事情metafactory意味着一個類中的類? – Katoch

+0

@Katoch:一個metafactory是一個爲你生成其他類的類。在這裏,'Update'和'Clear'是在每個使用點爲你生成正確的嵌套'Event'類的元分析。我[問另一個問題](http://stackoverflow.com/q/19187469/1329652)獲取社區反饋,瞭解是否有任何簡單的方法。 –

+0

我會建議我們的工作也可以在不使用模板類的情況下完成......因爲我們根本沒有在我們的字符串事件類中使用模板變量T ......如本例所示... http:// www .cprogramming.com/tutorial/templates.html ....你說什麼...? – Katoch