QEventLoop 的使用两例

熟悉的陌生人

Qt 是事件驱动的,所以当你用Qt的时候,几乎时时刻刻和 QEventLoop 打交道、,只是你可能没有意识到:

    QCoreApplicaton::exec()
    QApplication::exec()
    QDialog::exec()
    QThread::exec()
    QDrag::exec()
    QMenu::exec()
    ...

在前面列出的这些常见函数的背后,都有各自的QEventLoop,可能是我们很少有机会想到自己显式使用QEventLoop的缘故吧,对这个类似乎总是有些陌生。

------

  这些都开启了事件循环,事件循环首先是一个无限“循环”,程序在exec()里面无限循环,能让跟在exec()后面的代码得不到运行机会,直至程序从exec()跳出。从exec()跳出时,事件循环即被终止。QEventLoop::quit()能够终止事件循环。

  事件循环实际上类似于一个事件队列,对列入的事件依次的进行处理,当时间做完而时间循环没有结束的时候,其实际上比较类似于一个不占用CPU事件的for(;;)循环

  其本质实际上是以队列的方式来重新分配时间片

https://www.cnblogs.com/-wang-cheng/p/4973021.html

------

在 如何让 Qt 程序的 Sleep 和 QDialog 模态对话框与事件循环 两个短文中,我们可以看到 QEventLoop 的使用。那么?如何自己使用 QEventLoop 的,又有什么用呢?

QEventLoop

Manual 中说的很简洁

At any time, you can create a QEventLoop object and call exec() on it to start a local event loop. From within the event loop, calling exit() will force exec() to return.

在任何时候,你都可以创建一个QEventLoop的对象,然后调用它的exec() 来开始一个局部的事件循环。

看Manual容易让人头大,那么,看例子吧:

让主线程等待100ms?

直接sleep一下行么,显然,如果你的用户不介意你的程序界面不响应用户操作,没问题!可是如果介意呢?

此时,开启一个局部的事件循环,让其执行100ms后自己退出,似乎很不错。写来看看:

QEventLoop eventloop;
QTimer::singleShot(100, &eventloop, SLOT(quit()));
eventloop.exec();
    创建事件循环

启动定时器,

让其100ms后触发事件循环的quit()槽启动事件循环

注:让主线程等待有其他方法,此处略过。

窗口一闪而过?

不少人遇到过这个问题:在一个槽函数内创建了一个窗口对象,却没有看到窗口弹出来,或者看到窗口一闪而过。比如:

void XXXX::slot1()
{
    QDialog dlg;
    dlg.show()
}

当然,大家都知道原因:因为到了后面的大括号处,dlg因为出作用域,会被析构掉。解决方法很简单,增大w的生存时间即可。比如:

  • 将 dlg 作为类的成员,而不是函数的局部变量

  • 将 dlg 前面添加 static,作为静态成员

  • 将 dlg 用 new 分配到 heap 中

  • ...

能否用 QEventLoop 来解决呢?答案是,可以

void XXXX::slot1()
{
    QDialog dlg;
    dlg.show()
    QEventLoop loop;
    connect(&dlg, SIGNAL(finished(int)), &loop, SLOT(quit()));
    loop.exec(QEventLoop::ExcludeUserInputEvents);
}

恩至此,问题解决。其实,这也是 QDialog::exec() 内部所做的事情,只不过此处不是模态对话框而已。

————————————————

版权声明:本文为CSDN博主「dbzhang800」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/dbzhang800/article/details/6300519

关于Qt的事件循环以及QEventLoop的简单使用

https://www.cnblogs.com/-wang-cheng/p/4973021.html

还有,比如说对于一个槽函数,触发之后会弹出一个dialog,但是像下面这样写的话,窗口会一闪而过的

关于qt:QEventLoop的正确用法

https://www.codenong.com/29449561/

第一个示例中,当finished(QNetworkReply*)发出时,循环将退出。但是如果manager->get( request );导致finished(QNetworkReply*)信号在连接循环退出之前发出该怎么办?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值