美文网首页
Qt为自己的程序建立一个消息循环

Qt为自己的程序建立一个消息循环

作者: Joe_HUST | 来源:发表于2017-12-03 23:10 被阅读0次
    • 一般事件循环都是由exec()来开启的,如:
    QCoreApplicaton::exec()
    QApplication::exec()
    QDialog::exec()
    QThread::exec()
    QDrag::exec()
    QMenu::exec()
    
    • 事件循环是一个无限循环,程序在exec()里面无限循环,能让跟在exec()后面的代码得不到运行的机会,直到exec()跳出。从exec()中跳出时,事件循环会被终止。QEventLoop::quit()能够终止事件循环。事件循环实际上类似于一个事件队列,对列入的事件依次的进行处理,当时间做完而事件循环没有结束的时候,其实际上比较类似于一个不占用CPU事件的for(;;)循环。
    • 事件循环是可以嵌套的,当在子事件循环中的时候,父事件循环中的事件实际上是处于中断的状态,当子循环跳出exec()之后才可以执行父循环中的事件。但是此时并不代表父循环中的界面响应会被中断,因为往往子循环中也会有父循环的大部分事件,执行QMessageBox::exec(),QEventLoop::exec()的时候,虽然这些exec()打断了main函数中的QApplication::exec(),但是由于GUI界面的响应已经被包含在子循环当中,所以GUI界面依然能够得到响应。
    • 如果某一个子事件的循环仍然有效,但是其父循环被强制跳出,此时父循环不会立即执行跳出,而是等待子事件循环跳出后,父循环才会跳出。

    如果希望将主线程等待100ms,不能使用sleep来完成这个过程,那样会导致GUI界面停止响应。但是利用事件循环就可以避免这一点:

    QEventLoop loop;
    QTimer::singleShot(100,&loop,SLOT(quit()));
    loop.exec();
    

    若在一个槽函数中创建一个对象如下:

    void myDialog:: on_pushButton_clicked()
    {
      QDialog dlg;
      dlg.show();
    }
    

    此时我们会看不到dlg窗口或者是看到窗口一闪而过。因为我们的dlg会因为出了作用域而被析构掉。解决的办法很简单。

    1. 将 dlg 作为类的成员,而不是函数的局部变量
    2. 将 dlg 前添加static作为静态成员
    3. 将 dlg 用new分配到heap当中
    4. 使用事件循环
    void myDialog::on_pushButton_clicked()
    {
      QDialog tDlg;
      tDlg.show();
      QEventLoop tloop;
      connect(&tDlg,SIGNAL(finished(int)),&tloop,SLOT(quit()));
      tloop.exec(QEventLoop::AllEvents);
    }
    

    相关文章

      网友评论

          本文标题:Qt为自己的程序建立一个消息循环

          本文链接:https://www.haomeiwen.com/subject/wrkzbxtx.html