传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作。如果用户调用一个比较耗时的操作,就会冻结界面响应。

一个解决方法是按照事件处理的思路:

调用 Void QApplication::processEvents() 或 void QApplication::processEvents ( int maxtime ) 来强迫事件循环进行,但是这种做法是有潜在风险的。按照QCoreApplication:processEvents()可能会引起递归,导致栈溢出崩溃的说法,当主线程在某个槽函数里正在执行processEvents时, 刚好有一个能响应此槽函数的信号发送过(肯定是其他线程发的信号), 这时就可能会发生可怕的递归, 导致栈溢出崩溃。 原因是processEvents在处理自己槽函数的事件时,又会调用到processEvents,进入到无尽的递归中。

另外一个解决方法是:采用多线程。、

QT QThread多线程编程的方法一直有个争议,就是Bradley T. Hughes:You’re doing it wrong 归纳为3中方法优劣问题:

方法(1): 
1. 不使用事件循环。这是官方的 Manual 、example 以及相关书籍中都介绍的一种的方法。 
a. 子类化 QThread 
b. 重载 run 函数,run函数内有一个 while 或 for 的死循环 
c. 设置一个标记为来控制死循环的退出。

这里的run函数自己执行了一个循环,不需要事件循环机制了。

方法(2):

这种方法也是Bradley T. Hughes极力批判的 a. 子类化 QThread, b. 重载 run 使其调用 QThread::exec() c. 并为该类定义信号和槽,这样一来,由于槽函数并不会在新开的 thread 运行,很多人为了解决这个问题在构造函数中调用 moveToThread(this); 
而争论和不解正是这样的一条语句造成的。 
Bradley T. Hughes 给出说明是: QThread 应该被看做是操作系统线程的接口或控制点,而不应该包含需要在新线程中运行的代码。需要运行的代码应该放到一个QObject的子类中,然后将该子类的对象moveToThread到新线程中。

方法(3): 
在Qt4.3(包括)之前,run 是虚函数,必须子类化QThread来实现run函数。而从Qt4.4开始,qthreads-no-longer-abstract ,run 默认调用 QThread::exec() 。这样一来不需要子类化 QThread 了,只需要子类化一个 QObject 就够了,这正是被 Bradley T. Hughes推荐的方法。

方法如下

QThread thread;
Object obj;
Dummy dummy;
obj.moveToThread(&thread);
QObject::connect(&dummy, SIGNAL(sig()), &obj, SLOT(slot()));
thread.start();

所以,方法(1)和方法(3)是正确的QT QThread多线程编程方法,方法(2)用的最多,但只是三人成虎,一种不恰当的用法

http://blog.csdn.net/bladeandmaster88/article/details/51802491

最新文章

  1. 使用Django建立网站
  2. Django-简单项目创建
  3. ON DUPLICATE KEY UPDATE
  4. 42. Subsets && Subsets II
  5. (转)SpringSecurity扩展User类,获取Session
  6. struts中拦截器的开发
  7. java读取大容量excel之二(空格、空值问题)
  8. [C# 网络编程系列]专题六:UDP编程
  9. MiniUI学习笔记1
  10. 家庭版Windows10没有远程桌面的问题
  11. linux bash shell:最方便的字符串大小写转换(lowercase/uppercase conversion) (转)
  12. 在win10 64位系统安装 lxml (Python 3.5)
  13. Springboot中如何在Utils类中使用@Autowired注入bean
  14. Mysql 用户权限管理
  15. GZIPOutputStream GZIPInputStream
  16. iOS第三方登录qq
  17. Nexus6p:正在下载系统更新,没有进度
  18. cobbler配置解析
  19. NOIp2018提高组游记
  20. Oracle VirtualBox 问题汇总

热门文章

  1. M创aterial Design作风Android申请书--创建列表和卡
  2. iOS项目double、float精度丢失解决办法
  3. 编译和使用jasper库的一个注意事项
  4. vue-router设置页面标题
  5. 开发Android项目中使用androidannotations
  6. UVA - 10312 Expression Bracketing
  7. P和P1指向了O和O1两个变量(对象)的地址, 而不是O和O1的内容(对象的实际地址)——充分证明@是取变量(对象)的地址,而不是变量里面的内容,够清楚!
  8. 将指定路径下的所有SVG文件导出成PNG等格式的图片(缩略图或原图大小)
  9. cefsharp 与webbrowser简单对比概述
  10. 使用HANDLE_MSG宏简化Win32应用的开发