C++ Qt:定义自定义事件类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2248009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:41:32  来源:igfitidea点击:

Qt: Defining a custom event type

c++qtqt4

提问by Chris

I have created a custom event in my Qt application by subclassing QEvent.

我通过继承 QEvent 在我的 Qt 应用程序中创建了一个自定义事件。

class MyEvent : public QEvent
{
  public:
    MyEvent() : QEvent((QEvent::Type)2000)) {}
    ~MyEvent(){}
}

In order to check for this event, I use the following code in an event() method:

为了检查此事件,我在 event() 方法中使用以下代码:

if (event->type() == (QEvent::Type)2000)
{
  ...
}

I would like to be able to define the custom event's Type somewhere in my application so that I don't need to cast the actual integer in my event methods. So in my event() methods I'd like to be able to do something like

我希望能够在我的应用程序中的某处定义自定义事件的类型,这样我就不需要在我的事件方法中转换实际的整数。所以在我的 event() 方法中,我希望能够做类似的事情

if (event->type() == MyEventType)
{
  ...
}

Any thoughts how and where in the code I might do this?

任何想法我可以在代码中如何以及在何处执行此操作?

回答by Georg Fritzsche

If the event-type identifies your specific class, i'd put it there:

如果事件类型标识您的特定类,我会将它放在那里:

class MyEvent : public QEvent {
public:
    static const QEvent::Type myType = static_cast<QEvent::Type>(2000);
    // ...
};

// usage:
if(evt->type() == MyEvent::myType) {
    // ...
}

回答by Ostap

For convenience, you can use the QEvent::registerEventType() static function to register and reserve a custom event type for your application. Doing so will allow you to avoid accidentally re-using a custom event type already in use elsewhere in your application.

为方便起见,您可以使用 QEvent::registerEventType() 静态函数为您的应用程序注册和保留自定义事件类型。这样做将允许您避免意外重复使用已在应用程序其他地方使用的自定义事件类型。

Example:

例子:

class QCustomEvent : public QEvent
{
public:
    QCustomEvent() : QEvent(QCustomEvent::type())
    {}

    virtual ~QCustomEvent()
    {}

    static QEvent::Type type()
    {
        if (customEventType == QEvent::None)
        {
            int generatedType = QEvent::registerEventType()
            customEventType = static_cast<QEvent::Type>(generatedType);
        }
        return customEventType;
    }

private:
    static QEvent::Type customEventType;
};

QEvent::Type QCustomEvent::customEventType = QEvent::None;

回答by Reinstate Monica

The idiomatic way of dealing with such problems is to create a template wrapper class, leveraging CRTP. For each custom event type, such template represents a new type, thus a separate staticType()member exists for each type, returning its unique registered type.

处理此类问题的惯用方法是创建一个模板包装类,利用CRTP。对于每个自定义事件类型,这样的模板代表一个新类型,因此staticType()每个类型都存在一个单独的成员,返回其唯一的注册类型。

Below I give three ways of identifying types:

下面我给出三种识别类型的方法:

  1. By staticType()-- this is only useful withinan invocation of the application, and is the type to be used with QEvent. The values are not guaranteed to stay the samebetween invocations of an application. They do notbelong in durable storage, like in a log.

  2. By localDurableType()-- those will persist between invocations and between recompilations with the same compiler. It saves manual definition of durableType()method when defining complex events.

  3. By durableType()-- those are truly cross platform and will be the same unless you change the event class names within your code. You have to manually define durableType()if you're not using the NEW_QEVENTmacro.

  1. By staticType()- 这仅应用程序的调用中有用,并且是与 一起使用的类型QEvent。这些值不能保证在应用程序调用之间保持不变。它们属于持久存储,例如在日志中。

  2. By localDurableType()-- 这些将在调用之间和使用相同编译器的重新编译之间持续存在。durableType()在定义复杂事件时,它节省了手动定义方法。

  3. By durableType()- 这些是真正的跨平台,除非您更改代码中的事件类名称,否则它们将是相同的。durableType()如果不使用NEW_QEVENT宏,则必须手动定义。

Both localDurableType()and durableType()differ betwen Qt 4 and 5 due to changes to qHash.

localDurableType()durableType()不同介乎Qt的4和5,由于更改qHash

You use the header in either of two ways:

您可以通过以下两种方式之一使用标头:

#include "EventWrapper.h"

class MyComplexEvent : public EventWrapper<MyComplexEvent> {
   // An event with custom data members
   static int durableType() { return qHash("MyEvent"); }
   ...
};

NEW_QEVENT(MySimpleEvent) // A simple event carrying no data but its type.

EventWrapper.h

事件包装器.h

#ifndef EVENTWRAPPER_H
#define EVENTWRAPPER_H

#include <QEvent>
#include <QHash>

template <typename T> class EventWrapper : public QEvent {
public:
   EventWrapper() : QEvent(staticType())) {}
   static QEvent::Type staticType() {
      static int type = QEvent::registerEventType();
      return static_cast<QEvent::Type>(type);
   }
   static int localDurableType() {
      static int type = qHash(typeid(T).name());
      return type;
   }
};

#define NEW_QEVENT(Name) \
   class Name : public EventWrapper< Name > \
   { static int durableType() { \
       static int durable = qHash(#Name); return durable; \
     } };

#endif // EVENTWRAPPER_H