如何将 QEvent 传递给接收者拥有的对象?

How can I pass a QEvent to an object owned by the receiver?

本文关键字:拥有 接收者 对象 QEvent      更新时间:2023-10-16

如何将类通过 QObject::event() 函数接收的事件传递给其数据成员之一,然后由该数据成员处理该事件?

例如,如果我有

class A
{
B b;
public:
event(QEvent *);   
//other members and functions
};

class B
{
public:
event(QEvent *);
//other members
};

假设我使用postEvent()将事件从另一个函数(事件过滤器)发送到A的对象,据我了解,Aevent()函数接收事件。有没有办法将事件传递给A的成员,B,然后由该成员处理该事件?

使用QCoreApplication::sendEvent

class B : public QObject
{
public:
bool event(QEvent *);
};
class A : public QObject
{
// Correct
B b{this};
// Wrong
B bad;
public:
bool event(QEvent * ev) override {
if (ev->type() == my_event_type) {
// Correct
return QCoreApplication::sendEvent(&b, ev);
// Wrong
return b.event(&ev);
}
return QObject::event(ev);
}
};

在 C++98 中,如果没有统一初始化,则必须改用初始值设定项列表:

class A : public QObject
{
B b;
public:
A(QObject * parent = 0) : QObject(this), b(this) {}
bool event(QEvent * ev) { /*...*/ };
};

要避免的陷阱

  1. B的亲子关系对于确保它与A位于同一线程中至关重要。A用户可以自由地将其移动到任何线程 - 这是QObject的合约(破坏它是一个坏主意)。当他们这样做时,sendEvent变成未定义的行为,除非B在同一线程中。确保相关对象遵循线程的规范方法将其更改为它们应跟踪的对象。

  2. 不要直接调用QObject::event():它只能由Qt调用,直接调用它会绕过事件过滤器,导致B的行为不像QObjectQObject契约的一部分是事件过滤器(在不同级别)可以修改其功能。直接调用event()会破坏B所有用户的LSP!:他们将使用QObject,但它不再像QObject那样工作。