Qt EventLoop使用原理

​Qt EventLoop建立一个局部的local event loop,但网上普遍就此结论,却没有阐述深入理解。

目录

event loop?

翻译总结:

那什么时候需要使用Qeventloop?

怎么判断没有事件循环?eventloop是如何划分的?

翻译总结:

使用实例:


event loop?

Qt EventLoop::exec介绍:

Enters the main event loop and waits until exit() is called. Returns the value that was passed to exit().

If flags are specified, only events of the types allowed by the flags will be processed.

It is necessary to call this function to start event handling. The main event loop receives events from the window system and dispatches these to the application widgets.

Generally speaking, no user interaction can take place before calling exec(). As a special case, modal widgets like QMessageBox can be used before calling exec(), because modal widgets use their own local event loop.

To make your application perform idle processing (i.e. executing a special function whenever there are no pending events), use a QTimer with 0 timeout. More sophisticated idle processing schemes can be achieved using processEvents().

翻译:

通过调用 EventLoop::exec函数,将启用事件处理以便接收系统事件,以及派发事件到部件中,通常没有用户交互的时候,才调用exec(),当然这也有例外,例如QMessage Box ,模态部件有自己的事件循环。

翻译总结:

        eventloop是用来系统事件接收和派送事件。

那什么时候需要使用Qeventloop?


 答:没有事件循环,但要事件循环的时候,或者 延迟,但不能阻塞GUI线程时等。GUI线程设计是响应用户交互,其耗时,睡眠函数等任务最好不要在GUI主线程中,以避免阻塞主线程。通常可以这样休眠:
 

1.

QTime time;

time.start();while(time.elapsed() < 5000)     //等待时间流逝5秒钟

    QCoreApplication::processEvents();   //处理事件

2.

 QEventLoop eventloop;

 QTimer::singleShot(5000, &eventloop, SLOT(quit()));

 eventloop.exec();

怎么判断没有事件循环?eventloop是如何划分的?


Qt thread中介绍:
Per-Thread Event Loop

Each thread can have its own event loop. The initial thread starts its event loop using QCoreApplication::exec(), or for single-dialog GUI applications, sometimes QDialog::exec(). Other threads can start an event loop using QThread::exec(). Like QCoreApplicationQThread provides an exit(int) function and a quit() slot.

An event loop in a thread makes it possible for the thread to use certain non-GUI Qt classes that require the presence of an event loop (such as QTimerQTcpSocket, and QProcess). It also makes it possible to connect signals from any threads to slots of a specific thread. This is explained in more detail in the Signals and Slots Across Threads section below.

QObject instance is said to live in the thread in which it is created. Events to that object are dispatched by that thread's event loop. The thread in which a QObject lives is available using QObject::thread().

The QObject::moveToThread() function changes the thread affinity for an object and its children (the object cannot be moved if it has a parent).

翻译总结:

每一个线程都有自己的事件循环,通过exec启用事件循环。线程中事件循环使得那些非GUI但需要事件循环的类能够正常运行,例如(QTimer,QTcpSocket)。也使得任何线程的信号能够连接一个特定线程的槽(意思:槽所在的线程中有event loop,那么其他线程信号就可以关联该槽)。

QObject在哪个线程中创建,就在那个线程中生存,派送到QObject的事件通过该线程的event loop所派送。从上图可以看出,线程中event loop不能被其他线程复用。

使用实例:

重写run函数,但无事件循环,能发信号,但thread内部槽函数不能使用。

#include <QCoreApplication>

#include "mythread.h"

int main(int argcchar *argv[])

{

    QCoreApplication a(argcargv);

    Mythread th;

    QObject::connect(&th,&Mythread::timeout,[=]()mutable{

         qDebug() << "timeout";

     });

    QObject::connect(&th,&Mythread::threadheart,[=]()mutable{

         qDebug() << "threadheart";

     });

    th.start();

    return a.exec();

}

#include "mythread.h"

#include <QEventLoop>

Mythread::Mythread()

{

}

void Mythread::run()

{

    QTimer timer;

    timer.setInterval(1000);

    connect(&timer,SIGNAL(timeout()),this,SIGNAL(timeout()));

    timer.start();

    while(1)

    {

        emit threadheart();

  

    }

}

#ifndef MYTHREAD_H

#define MYTHREAD_H

#include <QThread>

#include <QObject>

#include <QTimer>

class Mythread : public QThread

{

    Q_OBJECT

public:

    Mythread();

    void run () override;

signals:

    void threadheart();

    void timeout();

};

#endif // MYTHREAD_H

重写run函数,添加local事件循环,能发信号,thread内部槽函数能使用。

#include "mythread.h"

#include <QEventLoop>

Mythread::Mythread()

{

}

void Mythread::run()

{

    QTimer timer;

    timer.setInterval(1000);

    connect(&timer,SIGNAL(timeout()),this,SIGNAL(timeout()));

    timer.start();

    while(1)

    {

        emit threadheart();

         QEventLoop eventloop;  //添加事件循环。

         QTimer::singleShot(1000, &eventloopSLOT(quit()));

         eventloop.exec();

    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来回答您的问题。Qt中的事件过滤器(Event Filter)是一个对象,它可以拦截并处理所有的事件,例如鼠标事件、键盘事件等等。事件过滤器可以用于拦截事件并进行自定义处理,从而实现一些特殊的功能。 在Qt中,事件过滤器是通过重载QObjecteventFilter方法来实现的。当一个事件发生时,该事件会被发送到QObject对象的event方法中处理。如果该对象设置了事件过滤器,则事件会被先发送到事件过滤器的eventFilter方法中处理。在事件过滤器中,可以对事件进行拦截、修改或者直接处理,并返回一个布尔值来指示是否继续将事件传递给目标QObject对象。 以下是一个简单的示例代码,演示了如何在Qt使用事件过滤器: ```c++ // 创建一个事件过滤器对象 class MyEventFilter : public QObject { public: explicit MyEventFilter(QObject *parent = nullptr); protected: bool eventFilter(QObject *obj, QEvent *event) override; }; MyEventFilter::MyEventFilter(QObject *parent) : QObject(parent) { } bool MyEventFilter::eventFilter(QObject *obj, QEvent *event) { // 在这里处理事件 if (event->type() == QEvent::MouseButtonPress) { qDebug() << "Mouse button pressed!"; // 返回true表示事件被处理完毕,不会继续传递给目标QObject对象 return true; } // 返回false表示事件继续传递给目标QObject对象 return QObject::eventFilter(obj, event); } // 将事件过滤器对象安装到目标QObject对象上 QObject *targetObject = ...; MyEventFilter *eventFilter = new MyEventFilter(); targetObject->installEventFilter(eventFilter); ``` 在上述代码中,我们创建了一个MyEventFilter来作为事件过滤器对象。在eventFilter方法中,我们判断了当前事件的型,如果是鼠标按下事件,则输出一条调试信息,并返回true,表示事件已经被处理完毕。如果不是鼠标按下事件,则返回false,表示事件继续传递给目标QObject对象。 最后,我们将事件过滤器对象安装到目标QObject对象上,这样事件就会先被发送到事件过滤器中进行处理,然后再传递给目标QObject对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值