• 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 

    #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 

    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 

    #include 

    #include 

    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 

    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();

        }

    }

  • 相关阅读:
    计算机毕业设计ssm宠物商店信息展示与服务订购系统7q5ic系统+程序+源码+lw+远程部署
    java基于Springboot+vue 音乐播放器论坛交流管理系统 element 前后端分离
    LESS vs. SCSS:选择何种CSS预处理器?
    论文投稿指南——中文核心期刊推荐(计算机技术2)
    [unity]保存文件的路径设置
    Dubbo注册中心之Redis原理概述
    Nacos 长轮询实现方式-配置中心源码
    Stm32_标准库_16_串口&蓝牙模块_手机与蓝牙模块通信_手机传入信息能对芯片时间日期进行更改
    Oracle性能调优实践中的几点心得
    辉芒微IO单片机FT60F11F-MRB
  • 原文地址:https://blog.csdn.net/qq_39280795/article/details/127041594