QT 多线程 通过发送信号,主线程槽响应此信号, 显示的速度慢, 是什么原因

purplepare 2017-02-09 05:58:27
各位大神,我刚刚接触QT不久,现在遇到QT中多线程通过emit 发送图像给主线程,主线程的槽函数负责显示此图像。

在主界面中,有个九宫格的窗口,其中每个窗口对应一个线程,用于实时采集相机的图像,在子线程中,最后发射信号emit setImage(Qimage img, int index)给主线程。 主线程的槽函数Image_process(QImage img, int index),得到后,根据index,显示不同的图像,到对应的位置。


问题是,当只开一个线程,即一个相机时,主界面显示的图像很流畅,即一秒大概5张。但当九个线程同时运行时,主界面显示的图像很卡,即1秒显示一张,很不流畅。

我现在不知道如何优化程序:我怀疑的点:
1)QT 多线程发射信号给主线程,或者多线程的用法不对?
2) 电脑硬件问题:8G内存,cpu ->4核 i5 -4590@3.30GHZ

希望打给大神针对软件方面,给于指导。。。多谢
...全文
3422 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
曾经我是菜 2019-02-17
  • 打赏
  • 举报
回复
我觉得QT的多线程本来就很慢,拿超多线程互锁来比赛的话,QT比java慢20~30倍。QT比较适合做少量线程的程序,线程一多就会非常慢。
另外显示图像的计算量不是你能控制的,还有系统总线带宽是否足够,可能显示一个图像已经占用了大半的系统带宽了。
anrancc 2017-11-01
  • 打赏
  • 举报
回复
楼主,我也在实现类似的功能,我也是在子线程里用信号将摄像头的图片发给主线程,但是我的label只能显示一帧图像,然后opencv就报错说无法获得数据,之前不采用多线程是不报这个错的,球问楼主知道时什么原因吗
Guilty_666 2017-07-25
  • 打赏
  • 举报
回复 1
用内存队列或者用信号发送数据块指针就行,回收和释放逻辑自己控制下就行,谁说信号不能发送图片的(换成指针就行,嘿嘿)
taohe_0 2017-02-25
  • 打赏
  • 举报
回复
引用 7 楼 adeng1919 的回复:
我也有做过线程中处理图像数据然后发送给UI线程刷新,感觉Qt并不会实时刷新,而且累计一段时间之后才开始刷
为了效率考虑,Qt的事件系统会把paintEvent合并。 参考Qt助手: Qt also tries to speed up painting by merging multiple paint events into one. When update() is called several times or the window system sends several paint events, Qt merges these events into one event with a larger region (see QRegion::united()). The repaint() function does not permit this optimization, so we suggest using update() whenever possible.
taohe_0 2017-02-25
  • 打赏
  • 举报
回复
信号传QImage?对于大对象,是不是自己管理好一些?子线程将数据放入缓冲队列,主线程不断获取数据,这种“”生产者——消费者“”模型比较简单,主线程对显示的控制也比较强。 Qt中,UI的更新只能在主线程中完成,在子线程中更新UI是会出问题的。
fxbszj 2017-02-22
  • 打赏
  • 举报
回复
信号发送图片已经是神一般的存在了
  • 打赏
  • 举报
回复
引用 7 楼 adeng1919 的回复:
我也有做过线程中处理图像数据然后发送给UI线程刷新,感觉Qt并不会实时刷新,而且累计一段时间之后才开始刷
你可以自己主动刷新的用 repaint函数
懒懒的吉他手 2017-02-22
  • 打赏
  • 举报
回复
我也有做过线程中处理图像数据然后发送给UI线程刷新,感觉Qt并不会实时刷新,而且累计一段时间之后才开始刷
  • 打赏
  • 举报
回复
引用 2 楼 purplepare 的回复:
[quote=引用 1 楼 dell_tx 的回复:] 建议先定位时间浪费在哪个地方,比如发送信号和接收到信号的时间,处理图像的时间,可以打印一些日志
当一个线程的时候,处理时间很短,九个线程的时候,处理的时间就变长了,可能跟 父子窗口刷新问题,界面频繁刷新 是否处理的过来有关?[/quote] 不对,既然是9个线程,那各个线程之间是互不影响的,也就是说9个线程耗费的时间应该与一个线程所耗费的时间一样才对,,,根据你的描述,感觉跟慢的原因很大可能跟主线程的图片处理显示有关系,频繁刷新,主线程的一个槽函数需要处理9个线程发送过来的图片,这个地方应该就是耗时所在,可以参考三楼的方法将图片的显示纳入子线程处理
niuren3000 2017-02-11
  • 打赏
  • 举报
回复 1
在窗口定义局部变量qimage,窗口paintevent中显示图片,线程中处理图片,处理完后发送一个信号,窗口槽收到信号this->repaint()一下就更新了,不用信号中带图片。
feiyangqingyun 2017-02-10
  • 打赏
  • 举报
回复
你可以试着将绘制图像的窗体指针传入线程,然后线程里面调用update,然后重写该界面的painevent方法,在里面绘制图片。
purplepare 2017-02-10
  • 打赏
  • 举报
回复
引用 1 楼 dell_tx 的回复:
建议先定位时间浪费在哪个地方,比如发送信号和接收到信号的时间,处理图像的时间,可以打印一些日志
当一个线程的时候,处理时间很短,九个线程的时候,处理的时间就变长了,可能跟 父子窗口刷新问题,界面频繁刷新 是否处理的过来有关?
  • 打赏
  • 举报
回复 1
建议先定位时间浪费在哪个地方,比如发送信号和接收到信号的时间,处理图像的时间,可以打印一些日志

16,210

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧