创造&发布定制的Qevent

时间:2013-10-02 10:28:40

标签: qt qevent

我必须创建2个自定义事件。 我按照这个链接&我的代码: - Is there a cleaner way to register Qt custom events?

这是创建&的正确方法吗?发布&将一些数据(Qstring)传递给自定义事件?

=============================================== ============

根据Kuba Ober 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文件: -

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上看到调试消息?

1 个答案:

答案 0 :(得分:0)

我只能评论您的事件实现的代码气味,因为此时不清楚为什么需要将事件发送到窗口中的编辑控件。后者是糟糕的设计。

你的活动课程不必要地复杂化。您应该在构建期间在事件内部设置所有值,然后应该可以通过只读访问器访问它们。额外的事件类型似乎也是一个不必要的噱头。

以下是我如何使用metafactory模式(我刚刚创造的名称,或许它有一个更好/现有的名称?)。这解决了需要显式派生类构造函数注入的问题。

为了便于理解,我将metafactory分成了小组成部分。

// 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::Event类是QEvent派生的自定义事件类。 Update :: Event的类层次结构如下所示(从最少派生类到最派生类):

  • 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的私有)。

事件处理程序中的用法如下所示:

void MainWindow::customEvent(QEvent *event)
{
   ...
   if (Update::Event::is(event)) {
      qDebug() << Update::Event::cast(event)->value();
      ...
   }
   else if (Clear::Event::is(event)) {
      ...
   }
   ...
}