2013-10-02 27 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