熟悉的陌生人

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

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

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

在  如何让 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() 内部所做的事情,只不过此处不是模态对话框而已。

http://blog.csdn.net/dbzhang800/article/details/6300519

如何让 Qt 的程序使用 Sleep(主线程没有Sleep函数,但线程可用自带的保护函数Sleep)的更多相关文章

  1. 通过使用Web Workers,Web应用程序可以在独立于主线程的后台线程中,运行一个脚本操作。这样做的好处是可以在独立线程中执行费时的处理任务,从而允许主线程(通常是UI线程)不会因此被阻塞/放慢。

    Web Workers API - Web API 接口参考 | MDNhttps://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API ...

  2. 有主线程发送message给子线程

    通常我们在处理耗时任务时候都会通过新建线程来处理,当任务处理完后通过Handler将结果发送回主线程.比如下面示例: package com.example.testlistener; import ...

  3. android4.0以上访问网络不能在主线程中进行以及在线程中操作UI的解决方法

    MONO 调用一个线程操作UI 然后报Only the original thread that created a view hierarchy can touch its views.错误 goo ...

  4. 03_主线程联网问题&ANR&子线程不能修改UI

    如果不使用HAXM,恐怕网页源码查看器无法获取servlet的源码.初步猜测是安卓模拟器运行速度太慢了.如果CPU不支持VT-x的话,HAXM是安装不上的.所以可以先开启VT-x. 可以参考几篇文章h ...

  5. Qt自己定义事件实现及子线程向主线程传送事件消息

    近期在又一次学习Qt的时候,由于要涉及到子线程与主线程传递消息,所以便琢磨了一下.顺便把有用的记录下来,方便自己以后查询及各位同仁的參考! 特此声明,本篇博文主要讲述有用的,也就是直接说明怎么实现,就 ...

  6. (转)C#/.NET主线程与子线程之间的关系

    一般 一个应用程序就对应一个进程,一个进程可有一个或多个线程,而一般有一个主线程.       有的博客上说“至少一个主线程”,这一说法持有怀疑         主线程与子线程之间的关系        ...

  7. Android子线程更新UI主线程方法之Handler

    背景: 我们开发应用程序的时候,处于线程安全的原因子线程通常是不能直接更新主线程(UI线程)中的UI元素的,那么在Android开发中有几种方法解决这个问题,其中方法之一就是利用Handler处理的. ...

  8. Java线程池主线程等待子线程执行完成

    今天讨论一个入门级的话题, 不然没东西更新对不起空间和域名~~ 工作总往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. 一 ...

  9. java主线程结束和子线程结束之间的关系

    (一)Main线程是个非守护线程,不能设置成守护线程. 这是因为,main线程是由java虚拟机在启动的时候创建的.main方法开始执行的时候,主线程已经创建好并在运行了.对于运行中的线程,调用Thr ...

随机推荐

  1. cxgrid按条件计算合计值 TcxTreeList计算合计值

    在Footer的第一列显示[合计:] 加一个Summary项,Column设为Grid的第一列,Kind设为skNone 在该Summary项的OnGetText事件中,输入: procedure T ...

  2. 关于我们 HerlMax(赫马克斯),奢侈品顶级服装高级定制品牌!

    关于我们 HerlMax(赫马克斯),奢侈品顶级服装高级定制品牌! HerlMax品牌拥有着纯正悠远的意大利高级定制文化,带着对神秘东方的向往,荣耀登入中国市场.

  3. Java中setCharAt()方法介绍

    --转载自网络,备忘 这是StringBuffer类里面的一个方法:主要是用来替换的,方法里面有两个参数setCharAt(int index,Char ch),第一个参数是取代的位置 索引从0开始 ...

  4. AvalonEdit 对于选定的文本添加前缀和后缀

    1: /// <summary> 2: /// 两边追加标志 3: /// </summary> 4: /// <param name="syntax" ...

  5. Wamp集成环境安装

    一.Wamp下载 点我下载WampServer2.1a-x32 二.Wamp安装步骤 三.修改语言为汉语 四.查看测试页面

  6. 【C#正则基础】正则表达式

    1. 代表任意多个字符:(.*?)2. 代表网页里的<body>*</body>任意的标签内容,替换以后网页源码就只剩纯文本:<[^>]*>3. 代表网页中的 ...

  7. ios NSString 去除空格和回车

    去除两端空格 NSString *temp = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCh ...

  8. 用python演示一个简单的AST(抽象语法树)

    如果对'a + 3 * b'进行解释,当中a=2,b=5 代码非常easy,就不再进行具体的解释了. Num = lambda env, n: n Var = lambda env, x: env[x ...

  9. [React] React Router: setRouteWillLeaveHook

    setRouteWillLeaveHook provides a method for us to intercept a route change before leaving the curren ...

  10. Sqlserver2012数据库乱码的解决方法

    Sqlserver2012数据库乱码的解决方法 1.      在创建数据库时,一定要指定数据库的排序规则 2.      输入数据库名称 3.      选中选项,在排序规则中选中Chinese_P ...