文档章节

保持Qt GUI响应的几种方法

 当当当当蛋糕
发布于 2016/11/14 16:49
字数 1076
阅读 21
收藏 0

最开始使用Qt时就遇到过QT Gui失去响应的问题,我是用多线程的方式解决的,然而通常来说,多线程是会降低程序的运行速度。

之后,在使用QSqlQuery::execBatch()函数时,Qt Gui 又失去响应,虽然多线程可以解决,但是如果能用单线程很好解决的,最好不要用到多线程,因为多线程不仅容易拖慢程序的速度,编程及维护的难度也更大,能用简单方法解决的,就不要用复杂的方法。

于是我再次搜索资料,期望在解决方案的选择与解决步骤上,能够得到一个全面而又细致的总结。

 

所以本文是在此文基础上的部分翻译、理解与二次总结。总之,有删减,有补充,所以没写 '转' 字。

一、问题的来源与分析

     首先,我们要知道 “为什么Qt Gui 会停止响应?”。简明扼要的说就是:长时间的密集处理或等待阻塞了Qt的事件循环,应用程序不能响应来自窗口系统的事件请求(《C++ Gui Qt4》 P135中有描述)。   那么多长算长呢?一秒钟算长,两秒钟太长。

     其次,“ 何种情形下会发生该问题? ”。可分为两种情形:

     第一,长时间按顺序执行的密集运算,全部计算结束后才能继续执行,如快速傅立叶变换。

     第二,“ 触发 ”了某项操作,该操作完成后才能进行“ 下一步 ”, 所以这里描述的是异步操作,如保存文件操作,服务器等待连接、网络下载等。详细见附注(1).

     私以为两种情形并无明显的概念上的区分,本质是一样的,但两种情形有不同的处理方法,特别是第二种情形, 在Qt框架下 ,用Qt的信号和槽机制往往可以解决阻塞问题,如QTcpServer::newConnection信号通知连接的到来,QIODevice::bytesWritten()与 QIODevice::readyRead()通知文件的读写,它们都是以非阻塞的形式实现相关功能的利器。 而第一种情形,不仅所有的事件循环停止了,信号和槽也暂时被忽视。我们将针对以上两种情形寻找解决方案。

     最后,我们考虑是否可以把这个造成 Qt Gui 停止响应的罪魁祸首大卸八块,即把他拆分成一个个小块,如果可以拆分,那么每块之间是依赖还是独立,如果独立那问题好办,放在不同的位置独立运作,否则,我们只能同步的执行,而最差的结果是——根本无法拆分!!

     总之,考虑以上信息差异,执行不同的解决方案。

二、解决方案

Manual event processing(人工执行事件)

     保持事件循环有一种最基本的方法——让程序去处理 悬挂事件好了 ,处理完了再回来继续我的后续运算,要做到这一点,就要在我的运算代码中间加上处理事件的代码,这句代码就是 QCoreApplication::processEvents();,只要该句代码能够周期性的被执行,就能保持Qt Gui的响应。

//代码来源于上述链接所指向文章

复制代码

for (int i = 3; i <= sqrt(x) && isPrime; i += 2) {
        label->setText(tr("Checking %1...").arg(i));
        if (x % i == 0)
            isPrime = false;
        QCoreApplication::processEvents();
        if (!pushButton->isChecked()) {
            label->setText(tr("Aborted"));
            return;
        } 

    }

复制代码

部分翻译(略)——可查看 Jason Lee的翻译

     该方案除了 具有Witold Wysota文中 所提到缺点之外,《C++ Gui Qt4》P135中还提到,用户可能会在应用程序还在执行某种操作时,或者关闭了主窗口,或者通过界面再次触发相同操作,这样就会产生不可预料的后果,如 一个保存文件对话框,用户单击save按钮后,程序开始磁盘文件的写入操作,该操作还未完成时,用户再次单击了关闭按钮,或者再次单击save按钮。书中给出的解决办法是将 qApp->processEvents()替换为qApp-> processEvents(QEventLoop::ExcludeUserInputEvents),以告诉Qt忽略鼠标事件和键盘事件。

本文转载自:

粉丝 0
博文 38
码字总数 13194
作品 0
南京
私信 提问
Python GUI教程(十三):在GUI中绘制K线图

文章首发个人博客:http://zmister.com Python GUI教程(一):在PyQt5中创建第一个GUI图形用户界面 Python GUI教程(二):添加窗口小部件到图形用户界面GUI中 Python GUI教程(三):在GUI...

州的先生
2017/12/01
0
0
保持Qt程序中GUI的响应流畅

如何使Qt 平台中的GUI保持响应流畅?一般来说耗时较长的操作,分为计算密集型操作和IO密集型操作,对于这两类操作如何提高响应速度。 而从操作的本质上来说,操作又可分为不可分解操作,如在...

水海云
2012/03/24
0
0
如何保持GUI的响应流畅(QT平台)

引子   一般来说耗时较长的操作,分为计算密集型操作和IO密集型操作,对于这两类操作如何提高响应速度呢?   而从操作的本质上来说,操作又可分为不可分解操作,如在第三方库中耗时较长的...

mickelfeng
2013/05/18
0
0
【Qt笔记】布局管理器

所谓 GUI 界面,归根结底,就是一堆组件的叠加。我们创建一个窗口,把按钮放上面,把图标放上面,这样就成了一个界面。在放置时,组件的位置尤其重要。我们必须要指定组件放在哪里,以便窗口...

大道无名
2016/07/29
36
0
QtRuby

Qt是Trolltech创建并发布的一个GUI工具包。Qt旨在成为多平台工具包,为Windows、Mac和UNIX操作系统提供一致的编程接口。开发人员只需编写代码一次,就可以在这三种平台上编译,而不需要做任何...

匿名
2009/01/02
3.4K
0

没有更多内容

加载失败,请刷新页面

加载更多

Oracle SQL语法实例合集

如需转载请注明出处https://my.oschina.net/feistel/blog/3052024 目的:迅速激活Oracle SQL 参考:《Oracle从入门到精通》 ------------------------------------------------------------......

LoSingSang
今天
1
0
增加 PostgreSQL 服务进程的最大打开文件数

https://serverfault.com/questions/628610/increasing-nproc-for-processes-launched-by-systemd-on-centos-7 要在systemd的配置里加才行...

helloclia
今天
2
0
组合模式在商品分类列表中的应用

在所有的树形结构中最适合的设计模式就是组合模式,我们看看常用商品分类中如何使用。 先定义一个树形结构的商品接口 public interface TreeProduct { List<TreeProduct> allProducts(...

算法之名
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部