Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt postEvent()和事件筛选器_Qt_Qevent_Qt Events - Fatal编程技术网

Qt postEvent()和事件筛选器

Qt postEvent()和事件筛选器,qt,qevent,qt-events,Qt,Qevent,Qt Events,我想通过QCoreApplication::postEvent(…)过滤发送给我的工作线程QThread的一些不需要的事件,然后再在事件循环中实际处理它。 事件过滤器何时实际过滤事件:在调用线程的postEvent()中,还是稍后在QThread事件循环中? 我认为答案是“在事件循环中”,但我在qt文档中找不到确切问题的答案。工作者和它的事件过滤器需要生活在同一个线程中。事件由线程的事件循环拾取,并在传递到其接收器QObject(当过滤器允许时)之前通过过滤器。下面是一个演示此行为的示例:

我想通过
QCoreApplication::postEvent(…)
过滤发送给我的工作线程
QThread
的一些不需要的事件,然后再在事件循环中实际处理它。

事件过滤器何时实际过滤事件:在调用线程的
postEvent()
中,还是稍后在
QThread
事件循环中?


我认为答案是“在事件循环中”,但我在qt文档中找不到确切问题的答案。

工作者和它的事件过滤器需要生活在同一个线程中。事件由线程的事件循环拾取,并在传递到其接收器
QObject
(当过滤器允许时)之前通过过滤器。下面是一个演示此行为的示例:

#include <QtCore>

//a thread that can be destroyed at any time
//see http://stackoverflow.com/a/25230470
class SafeThread : public QThread{
    using QThread::run;
public:
    explicit SafeThread(QObject *parent = nullptr):QThread(parent){}
    ~SafeThread(){ quit(); wait(); }
};

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

//worker QObject that handles MyEvent by printing a message
class Worker : public QObject {
public:
    explicit Worker(QObject *parent = nullptr):QObject(parent){}
    bool event(QEvent *event) {
        if(event->type() == MyEvent::myType) {
            qInfo() << "event in thread: " << QThread::currentThreadId();
            return true;
        }
        return QObject::event(event);
    }
};

class EventFilter : public QObject {
public:
    explicit EventFilter(QObject *parent = nullptr):QObject(parent){}
    bool eventFilter(QObject *watched, QEvent *event) {
        if(event->type() == MyEvent::myType) {
            qInfo() << "filter in thread: " << QThread::currentThreadId();
            return false; //do not filter the event
        }
        return QObject::eventFilter(watched, event);
    }
};


int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    //create worker and thread
    Worker worker;
    EventFilter filter;
    SafeThread thread;
    filter.moveToThread(&thread);
    worker.moveToThread(&thread);
    worker.installEventFilter(&filter);
    thread.start();

    qInfo() << "calling postEvent from thread: " << QThread::currentThreadId();
    QCoreApplication::postEvent(&worker, new MyEvent());

    QTimer::singleShot(1000, &a, &QCoreApplication::quit);
    return a.exec();
}

必须在事件传递时执行筛选,因为筛选器希望目标对象存在并具有可访问状态。这种存在和状态只能在事件交付时得到保证。使用
QObject
的方法是不安全的,保存从其他线程中选择的一些方法是不安全的,因此通常在发布事件时,不可能安全地访问目标对象。只有当对象的生命周期得到保证,并且使用线程安全的方法访问状态,并且这种方式不会导致死锁时,才有可能执行此操作。

我不太确定您在问什么,但可能是您想要的。再看一看,好的。但是什么时候实际执行过滤呢?
calling postEvent from thread:  0xAAAA
filter in thread:  0xBBBB
event in thread:  0xBBBB