【问题标题】:create & post the customized Qevent创建并发布定制的 Qevent
【发布时间】:2013-10-08 17:09:39
【问题描述】:

我必须创建 2 个自定义事件。 我点击了这个链接并制作了我的代码:--
Is there a cleaner way to register Qt custom events?

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

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

按照 Kuba Ober 的建议编辑代码:---

Mainwindow.h :--

UpdateEvent *myUpdateEvent ;
ClearEvent *myClearEvent ;

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

【问题讨论】:

    标签: qt qevent


    【解决方案1】:

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

    您的 Event 类是不必要的复杂。您应该在构造期间设置事件内的所有值,并且之后应该可以通过只读访问器访问它们。额外的事件类型似乎也是一个不必要的噱头。

    我会这样做,使用元工厂模式(我刚刚创造的名称,也许有更好的/现有的名称?)。这解决了对显式派生类构造函数注入的需求,否则会需要。

    为了便于理解,我已将元工厂拆分为小的组成类。

    // 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&lt;EventMF&lt;...&gt;::EventFwd&gt;EventMF&lt;...&gt;::Final(多重继承)

    • EventMF&lt;Update, StringData&lt;Update&gt;&gt;::FinalWrapper

    • StringData&lt;Update&gt; = EventMF&lt;Update, StringData&lt;Update&gt;&gt;::Event

      EventMF&lt;...&gt;EventMF&lt;Update, StringData&lt;Update&gt; 的简写。

    Update::Event update("update") 行构造了一个自定义的带有字符串的事件实例,构造函数在上面的列表中从最后一个调用到第一个。

    由于EventMF&lt;...&gt; 是一个仅在编译时工作的元工厂,因此绝对不需要它的实例在运行时存在。因此EventMF&lt;...&gt;::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)) {
          ...
       }
       ...
    }
    

    【讨论】:

    • 谢谢 .. 从这个线程中学到了很多 c++ 概念... 最后一件事元工厂意味着类中的类?
    • @Katoch:元工厂是为您生​​成其他类的类。这里,UpdateClear 是元工厂,它们在每个使用点为您生成正确的嵌套 Event 类。我已经asked another question 获得社区反馈,了解是否有更简单的方法。
    • 我建议我们的工作也可以在不使用模板类的情况下完成……因为我们根本没有在字符串事件类中使用模板变量 T……如本例所示。 ..cprogramming.com/tutorial/templates.html ....你说什么...?
    • 好的,这就是为什么在 statictype() 函数中.. return static_cast<:type>(type); .. 声明将其类型转换为唯一类型 T .... 感谢了解完整的概念...!!
    • @Katoch:不,类型转换不是唯一类型,这仅仅是因为QEvent::Type 不是int,而是一个枚举。这是一条红鲱鱼。对于每个类型D,都有一个单独的EventWrapper&lt;D&gt;::staticType()。因此你有EventWrapper&lt;Update::EventFwd&gt;::staticType()EventWrapper&lt;Clear::EventFwd&gt;::staticType()。它们是编译器为您生成的独立函数。
    猜你喜欢
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多