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

时间:2017-02-20 19:11:32

标签: c++ qt events event-handling

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

例如,如果我有

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

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

假设我使用A将事件从另一个函数发送到postEvent()的对象,根据我的理解,event() A函数收到A事件。有没有办法将事件传递给BDatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference(); 的成员,然后处理该事件?

1 个答案:

答案 0 :(得分:2)

使用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不像QObject那样行事。 QObject合同的一部分是事件过滤器(在各个级别)可以修改其功能。直接调用event()会导致所有B个用户的LSP中断!:他们将使用QObject,但它会不再像QObject那样。