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

熟悉的陌生人

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

时间: 2024-08-05 23:40:38

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

主进程或者主线程是否会等待子线程或子进程的问题

1.主进程会等待所有子进程结束后才会程序结束 2.主线程也会等待所有子线程结束后才会主线程结束 3.from multiprocessing import Pool这个进程池,并不会等待所有的进程运行完成,而是主线程代码执行完成后程序就立即结束 . 所以这个进程池需要加p.close()和p.join() 4.from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor  的进程池和线程池,主进程或者主线程会等进程池内

有主线程发送message给子线程

通常我们在处理耗时任务时候都会通过新建线程来处理,当任务处理完后通过Handler将结果发送回主线程.比如下面示例: 1 package com.example.testlistener; 2 3 import java.util.Timer; 4 import java.util.TimerTask; 5 6 import android.app.Activity; 7 import android.content.res.Configuration; 8 import android.os.

Qt 定时器signal/slot阻塞主线程界面

示例代码: <span style="font-size:18px;">class bicycle : public QMainWindow { public slots: void uploadDeviceStatus(); }; bicycle::bicycle(QWidget *parent) : QMainWindow(parent) { QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout(

一个主线程下有多个子线程任务,主线程必须在100秒内将子线程执行的集合结果进行处理返回

实现代码: package cmd.chengxuyuanzhilu.async; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future;

android断点下载并显示进度,关于handle,和主线程不能联网采取子线程联网下载,和多线程下载学习

package cn.multidownload; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; import java.ne

遇到线程阻塞,主线程死亡的问题,线程与信号量的使用

最近使用阿里云的oss 上传文件遇到的问题 解决方式 外层加了队列,本文主要写线程和信号量  持续更新 dispatch_async(dispatch_get_global_queue(0, 0), ^{ // 分块上传 [upload multipartUpload:videoPath objectKey:objectKeyName]; if([[self viewController] respondsToSelector:@selector(creatBackViewForUpdatePr

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

近期在又一次学习Qt的时候,由于要涉及到子线程与主线程传递消息,所以便琢磨了一下.顺便把有用的记录下来,方便自己以后查询及各位同仁的參考! 特此声明,本篇博文主要讲述有用的,也就是直接说明怎么实现,就不打算陈述一大堆理论啦,只是,还是建议大家去查查对应的理论比較好.这样能对Qt的消息传送机制的理解更加深入. 依据网上大多数人的资料,要实现自己定义消息,须要从QEvent 派生一个自己定义的事件:事实上也能够不须要,仅仅要使用QEvent::Type自己定义一个事件即可了. 在这里,本人把两种实现

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

最近在重新学习Qt的时候,因为要涉及到子线程与主线程传递消息,所以便琢磨了一下,顺便把实用的记录下来,方便自己以后查询及各位同仁的参考! 特此声明,本篇博文主要讲述实用的,也就是直接说明怎么实现,就不打算陈述一大堆理论啦,不过,还是建议大家去查查相应的理论比较好,这样能对Qt的消息传送机制的理解更加深入! 根据网上大多数人的资料,要实现自定义消息,需要从QEvent 派生一个自定义的事件:其实也可以不需要,只要使用QEvent::Type自定义一个事件就行了.在这里,本人把两种实现方法都在这里讲

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

今天讨论一个入门级的话题, 不然没东西更新对不起空间和域名~~ 工作总往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了. 一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线程的流程,  往往需要让主线程指定后, 等待子线程的完成. 这里有几种方式. 站在 主线程的角度, 我们可以分为主动式和被动式. 主动式指主线主动去检测某个标志位, 判断子线程是否已经完成. 被动式指主线程被动的等待子线程的结束, 很明