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

        }

    }

  • 相关阅读:
    DAMA-DMBOK2重点知识整理CDGA/CDGP——第15章 数据管理成熟度评估
    【Javascript】弹出框
    基础知识集合
    快乐数[环类问题之快慢指针]
    如何在arXiv上发表一篇文章
    寒假作业2月13号
    计及电池储能寿命损耗的微电网经济调度(matlab代码)
    嵌入式分享合集100
    用Roslyn玩转代码之一: 解析与执行字符串表达式
    c++小游戏(更新中)
  • 原文地址:https://blog.csdn.net/qq_39280795/article/details/127041594