Qt 如何处理密集型耗时的事情
有时候需要处理一些跟界面无关的但非常耗时的事情,这些事情跟界面在同一个线程中,由于时间太长,导致界面无法响应,处于“假死”状态。例如:在应用程序中保存文件到硬盘上,从开始保存直到文件保存完毕,程序不响应用户的任何操作,窗口也不会重新绘制,从而处于“无法响应”状态,这是一个非常糟糕的体验 。
在这种情况下,有一种方法是使用多线程,即在子线程中处理文件保存,主线程负责界面相关。
而如果不想使用多线程,最简单的办法就是在文件保存过程中频繁调用QApplication::processEvents()。该函数的作用是让程序处理那些还没有处理的事件,然后再把使用权返回给调用者。
代码如下:
bool MyApp::writeFile(const QString &filename)
{
QFile file(filename);
...
QApplication::setOverrideCursor(Qt::WaitCursor);
for(int r = ; r != rowCount; ++r)
{
for(int c = ; c != colCount; ++c)
{
out << table(r,c);
qApp.processEvents();
}
}
QApplication::restoreOverrideCursor();
}
这样一来,程序就能响应了。
但是,该方法有一个问题:可能正在保存文件的过程中,用户不小心又单击了保存,或不小心关闭了程序主窗口,这样会产生意想不到的后果。
解决这个问题的最简单的办法是替换成:
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);//它可以忽略用户的输入(鼠标和键盘事件)。
进一步的,如果想显示一个带有进度条的对话框,随时显示当前的进度状态,可以使用QProgressDialog。
bool MyApp::writeFile(const QString &filename)
{
QFile file(filename);
...
QApplication::setOverrideCursor(Qt::WaitCursor);
QProgressDialog progress;
progress.setWindowTitle(tableData->sNameCH);
progress.setLabelText(QStringLiteral("数据保存中,请稍候..."));
//progress.setCancelButton(0);//不显示“取消”按钮
progress.setCancelButtonText("取消");
progress.setRange(,rowCount );
progress.setModal(true);
//此处没有调用show()来显示,是因为QProgressDialog会自动决定是否显示
//如果时间过短,就不会显示。
for(int r = ; r != rowCount; ++r)
{
progress.setValue(row);
//如果用户单击了“取消”,就取消保存文件,并删除该文件。
if(progress.wasCanceled)
{
file.remov();
return false;
}
for(int c = ; c != colCount; ++c)
{
out << table(r,c);
qApp.processEvents();
}
}
QApplication::restoreOverrideCursor();
}
显示效果如下:

Qt 如何处理密集型耗时的事情的更多相关文章
- Qt 如何处理密集型耗时的事情(频繁调用QApplication::processEvents)
有时候需要处理一些跟界面无关的但非常耗时的事情,这些事情跟界面在同一个线程中,由于时间太长,导致界面无法响应,处于“假死”状态.例如:在应用程序中保存文件到硬盘上,从开始保存直到文件保存完毕,程序不响 ...
- [C++]Qt 如何处理密集型耗时的事情(频繁调用QApplication::processEvents)
https://www.cnblogs.com/senior-engineer/p/5598133.html https://www.cnblogs.com/findumars/p/5607683.h ...
- Qt 如何处理拖放应用程序参数时,中国
你用 Qt 我们开发的应用程序.用户拖放文件到您的 exe 在.启动应用程序,在这个时候, main() 功能参数可以接收中国.如何正确处理它?非常easy,码如下面: QTextCodec *cod ...
- Qt经典—线程、事件与Qobject(耳目一新)
介绍 You’re doing it wrong. — Bradley T. Hughes 线程是qt channel里最流行的讨论话题之一.许多人加入了讨论并询问如何解决他们在运行跨线程编程时所遇到 ...
- Qt经典—线程、事件与Qobject
介绍 You’re doing it wrong. — Bradley T. Hughes 线程是qt channel里最流行的讨论话题之一.许多人加入了讨论并询问如何解决他们在运行跨线程编程时所遇到 ...
- 【Qt开发】事件循环与线程 一
事件循环与线程 一 初次读到这篇文章,译者感觉如沐春风,深刻体会到原文作者是花了很大功夫来写这篇文章的,文章深入浅出,相信仔细读完原文或下面译文的读者一定会有收获. 由于原文很长,原文作者的行文思路是 ...
- QT自绘标题和边框
在QT中如果想要自绘标题和边框,一般步骤是: 1) 在创建窗口前设置Qt::FramelessWindowHint标志,设置该标志后会创建一个无标题.无边框的窗口. 2)在客户区域的顶部创建一个自绘标 ...
- QT安装在VS2008中的方法
(一)工欲善其事,必先利其器,废话不多讲. 原文:http://www.cnblogs.com/zwq194/archive/2011/02/19/1958713.html 总结起来网上流行的VS20 ...
- Linux Qt使用POSIX多线程条件变量、互斥锁(量)
今天团建,但是文章也要写.酒要喝好,文要写美,方为我辈程序员的全才之路.嘎嘎 之前一直在看POSIX的多线程编程,上个周末结合自己的理解,写了一个基于Qt的用条件变量同步线程的例子.故此来和大家一起分 ...
随机推荐
- Binary safe
https://en.wikipedia.org/wiki/Binary-safe A binary-safe function is one that treats its input as a r ...
- Oracle 游标使用总结(好文章)
游标(CURSOR)也叫光标,在关系数据库中经常使用,在PL/SQL程序中可以用CURSOR与SELECT一起对表或者视图中的数据进行查询并逐行读取. Oracle游标分为显示游标和隐式游标. 显示游 ...
- 10.11NOIP模拟题(3)
/* 可以看出,对于一段区间[L,R]如果统计了答案 若a[L]<a[R],那么当右端点往左移时答案不会更优,a[R]>a[L]同理 所以两个指针分别从头尾往中间扫那边小移哪边即可. */ ...
- CentOS 6.5克隆后eth1与eth0的问题
CentOS 6.5克隆后eth1与eth0的问题 按照安装文档执行以下步骤时: 从克隆出来的虚拟机网卡都会被命名为eth1,而有些程序或者脚本,涉及到网卡的,默认写的是eth0,这时就存在要 ...
- 键盘按钮keyCode大全:获取按键对应的键值的方法
没有大全,只有方法,授人与鱼不如授人于渔: 下面这行代码,大家可以打在控制台里,直接进行测试: document.body.onkeyup = function (e) { e = e || wind ...
- SQL 索引篇
索引介绍: 1.索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息. 数据库索引好比是一本书前面的目录, SQL Server的B树结构 2.加快数据库的查询速 ...
- 思维+multiset ZOJ Monthly, July 2015 - H Twelves Monkeys
题目传送门 /* 题意:n个时刻点,m次时光穿梭,告诉的起点和终点,q次询问,每次询问t时刻t之前有多少时刻点是可以通过两种不同的路径到达 思维:对于当前p时间,从现在到未来穿越到过去的是有效的值,排 ...
- ViewPager(3)用viewpager实现tabhost
1.示例 2.代码 2.1 TabViewPagerMain.java import android.graphics.drawable.Drawable; import android.os.Bun ...
- 1、DOS基本命令
命令dir能给列出当前目录下面的所有文件.程序和子目录.所有目录(Windows 中称为文件夹)的目录名前面都有一个<DIR>标记.文件和程序名前面显示有这些文件和程序的大小. 想说的是, ...
- MongoDB学习笔记~复杂条件拼接和正则的使用
在大叔lind框架里有日志组件logger,而在日志实现方式上有file,mongodb,sql,json等方式,对分布式日志处理上大叔推荐使用mongodb进行存储,除了它的高效写入,灵活的结构外, ...