• 11546阅读
  • 8回复

[提问]【已解决】请教个多线程中某个线程占用很多资源导致界面假死的问题。 [复制链接]

上一主题 下一主题
离线chyaini
 

只看楼主 正序阅读 楼主  发表于: 2011-05-13
我在做一个图形处理的程序,其中对图像进行处理时会占用很多的内存和cpu,并且很耗时。如果都放在主线程中运行,会导致界面假死,无法响应操作。于是我想到了采用多线程方法来解决这个问题。在把耗时的处理部分放到子线程中时,因为这个处理会占用大量的资源(内存和cpu时间),所以主线程还是得不到运行,依然的假死状态。


以上问题描述。


下面描述我采用的方法:
先继承了QThread类,在myThread类里添加一个信号,在run()函数中发出这个信号,在调用这个线程是地方接受这个信号,触发一个slot,
  1. class myThread : public QThread
  2. {    
  3. Q_OBJECT
  4. public:      
  5.     explicit myThread(QObject *parent = 0);
  6. protected:  
  7.   void run() { emit threadSignal();};
  8. signals:
  9.    void threadSignal();
  10. }



下面是调用的代码:
  1.     
  2. m_Thread = new myThread();    
  3. connect(m_Thread, SIGNAL(threadSignal()), this, SLOT(testForThread2()));    
  4. m_Thread->start(QThread::NormalPriority);
  5. QProgressDialog progressDlg(tr("Creating Thumbnail..."), tr("cancel"), 0, 0);  
  6. progressDlg.setWindowModality(Qt::WindowModal);  
  7. progressDlg.exec();



我预期的目的是在这个耗时的处理运行时,会出现一个循环的进度条显示正在处理,如图1 。但实际结果是处理的时候这个进度条的窗口出现了,但是是处于假死状态,如图2

问题1:我采用的方法是否是正确的?
问题2:如果我采用的方法是正确的,那么这样问题是否还有其他好的解决方法?

望位大牛不吝赐教。
[ 此帖被chyaini在2011-05-16 10:19重新编辑 ]
win7+VS2010+Qt4.7+opencv2.2
图像处理
离线jxhxfen2008

只看该作者 8楼 发表于: 2013-03-12
引用第5楼dbzhang800于2011-05-13 12:27发表的  :
可以看看这个:
http://hi.baidu.com/cyclone/blog/item/65f3f603294f2e783812bb51.html


对啊,博客进不去,在么,大侠
离线honestapple

只看该作者 7楼 发表于: 2013-03-11
回 5楼(dbzhang800) 的帖子
我也想看你博客上的文章,但是发现博客上不去了。
离线chyaini

只看该作者 6楼 发表于: 2011-05-13
回 5楼(dbzhang800) 的帖子
看了你的博客的三篇文章,发现你写的真不错,浅显易懂。看完我感觉就是继承QObject,然后把其对象移动到新的线程中去,然后想办法调用其的槽。

这样的话还是一个QObject的子类只能进行一种处理啊,我这样理解对不对?
呃,想了想,QObject的子类可以定义多个slot,每个slot对应一种处理,这样是不是一个解决方法呢?
[ 此帖被chyaini在2011-05-13 16:31重新编辑 ]
win7+VS2010+Qt4.7+opencv2.2
图像处理
离线dbzhang800

只看该作者 5楼 发表于: 2011-05-13
离线chyaini

只看该作者 4楼 发表于: 2011-05-13
引用第3楼dbzhang800于2011-05-13 11:13发表的  :
先学习线程的使用吧,用法不对。所有耗时的操作你都放到了主线程中了

仔细想了想,发现好像是不对,testForThread()函数还是在主界面中,应该是主线程中运行。

按照文档中说的,继承QThread后重写run()函数,但是这样继承出的myThread只能进行一种既定的操作,即run()函数中的代码,不具有通用性啊。

怎么能写一个QThread的子类能通用呢?
win7+VS2010+Qt4.7+opencv2.2
图像处理
离线dbzhang800

只看该作者 3楼 发表于: 2011-05-13
先学习线程的使用吧,用法不对。所有耗时的操作你都放到了主线程中了
离线chyaini

只看该作者 2楼 发表于: 2011-05-13
引用第1楼jdwx于2011-05-13 10:25发表的  :
首先你处理一个图片用多少时间?QProgressDialog是智能的,要运行一段时间才出进度条。
可以考虑在主界面上放一个进度条,不用QProgressDialog。
还有progressDlg.exec();将导致主界面停止响应。


处理一幅图片大概需要几分钟。
progressDlg.exec();使用这句话是为了让进度条一直循环,直到处理结束,然后响应myThread的finish信号,kill掉进度条窗口。
win7+VS2010+Qt4.7+opencv2.2
图像处理
离线jdwx

只看该作者 1楼 发表于: 2011-05-13
首先你处理一个图片用多少时间?QProgressDialog是智能的,要运行一段时间才出进度条。
可以考虑在主界面上放一个进度条,不用QProgressDialog。
还有progressDlg.exec();将导致主界面停止响应。
发帖时要说明:操作系统、Qt版本、编译器,这样能更快的得到回复。
快速回复
限100 字节
 
上一个 下一个