QEventLoop 的使用

本文介绍了Qt中的QEventLoop类,详细解释了事件循环的概念及其在Qt中的应用方式。包括QEventLoop的基本使用方法、事件循环的嵌套以及如何利用QEventLoop实现同步调用等高级技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

前言

一、QEventLoop

二、使用步骤

三、 事件循环的嵌套及QEventLoop模拟同步调用

1、同步获取数据

2、主线程等待

3、对话框弹出



前言

事件循环本质上就是一个无限循环,不停地去获取下一个事件,然后做出处理;直到 quit 事件发生,循环结束。

一、QEventLoop

        其中exec是启动事件循环,调用exec以后,调用exec的函数就会被“阻塞”,直到EventLoop里面的while循环结束。

        QEventLoop 即 Qt 中的事件循环类,其中 exec 是启动事件循环,调用 exec 以后,调用 exec 的函数就会被“阻塞”,直到 EventLoop 里面的while循环结束。
一般当主线程需要等待某个条件成立才能继续执行,如果不想卡主界面,就可以使用 QEventLoop 实现。

二、使用步骤

QEventLoop loop;//定义一个事件循环
QTimer::singleShot(2000, &loop, SLOT(quit()));//创建单次定时器,槽函数为事件循环的退出函数
loop.exec();//事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出


三、 事件循环的嵌套及QEventLoop模拟同步调用


       事件循环是可以嵌套的,当在子事件循环中的时候,父事件循环中的事件实际上处于中断状态,当子循环跳出exec之后才可以执行父循环中的事件。当然,这不代表在执行子循环的时候,类似父循环中的界面响应会被中断,因为往往子循环中也会有父循环的大部分事件,执行QMessageBox::exec(),QEventLoop::exec()的时候,虽然这些exec()打断了main()中的QApplication::exec(),但是由于GUI界面的响应已经被包含到子循环中了,所以GUI界面依然能够得到响应。如果某个子事件循环仍然有效,但其父循环被强制跳出,此时父循环不会立即执行跳出,而是等待子事件循环跳出后,父循环才会跳出。


1、同步获取数据

经常会有这种场景: “触发 ”了某项操作,必须等该操作完成后才能进行“ 下一步 ”。比如:数据获取,向服务器发起登录请求后,必须等收到服务器返回的数据,才决定下一步如何执行。这种场景,如果设计成异步调用,直接用Qt的信号/槽即可,如果要设计成同步调用,就可以使用本地QEventLoop。

 
void A::onFinish(bool r, const QString &info)
{
   m_result = r;
   qDebug() << info;
 //槽中退出事件循环 
  loop.quit(); 
}​
 
bool A::get(const QString &userName, const QString &passwdHash, const QString &dataName)
 { 
    //声明本地EventLoop QEventLoop loop;
    m_result = false; 
   //先连接好信号 
   connect(&network, SIGNAL(finished(bool,const QString &)),this,SLOT(onFinish(bool,const QString &)));
 //发起登录请求 
  getData(userName, passwdHash, dataName); 
//启动事件循环。阻塞当前函数调用,但是事件循环还能运行。 
//这里不会再往下运行,直到前面的槽中,调用loop.quit之后,才会继续往下走
 loop.exec();
 //返回result。loop退出之前,m_result中的值已经被更新了。
 return m_result;
 }
 
​

2、主线程等待

比如说如果想要将主线程等待100ms,总不能使用sleep吧,那样会导致GUI界面停止响应的,但是用事件循环就可以避免这一点:

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

3、对话框弹出

void A::Show()
{
     QDialog dlg;
     dlg.show();
     QEventLoop loop;
     connect(&dlg, SIGNAL(finished(int)), &loop, SLOT(quit()));
     loop.exec(QEventLoop::ExcludeUserInputEvents);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值