• 2752阅读
  • 11回复

[讨论]高手进来帮忙看看,qt 多线程绘图,graphicsview等 [复制链接]

上一主题 下一主题
离线onlyone
 

只看楼主 倒序阅读 楼主  发表于: 2019-09-16


现在项目需要多线程绘图。在网上看到一个结论:QImage QPixMap 只要调用绘图功能,都只能在主线程GUI中调用。子线程是不能操作绘图函数的。
第一个问题:这个说法对吗?我自认为该说法是对的。网上有些在子线程调用drawline 等方法的例子,可能都是瞎倒腾。
第二个问题:如果真的只能在主线程绘图,那么是不是QT就没有办法多线程绘图了呢?

尤其是结合graphicsScene 等,如何进行多线程绘图?

离线汉阳青川

只看该作者 1楼 发表于: 2019-09-16
请深入学习理解一下MVC思想
离线笑颜

只看该作者 2楼 发表于: 2019-09-16
untitled18.rar (3 K) 下载次数:7

我简单试了试,不存在QImage不能在子线程绘制的说法啊!

void XYTestThread::run()
{
    QImage image(400, 400, QImage::Format_ARGB32_Premultiplied);
    QPainter painter(&image);
    painter.fillRect(image.rect(), QColor(rand() % 255, rand() % 255, rand() % 255));

    while (!mExit) {
        usleep(1000*30);
        painter.drawLine(QPoint(rand() % 400, rand() % 400),
                         QPoint(rand() % 400, rand() % 400));
        emit updateImage(image);
    }
}
离线onlyone

只看该作者 3楼 发表于: 2019-09-16
回 笑颜 的帖子
笑颜:[图片]
我简单试了试,不存在QImage不能在子线程绘制的说法啊!
void XYTestThread::run()
....... (2019-09-16 10:26) 

网上看过很多论点,都是说这样写,一时不会出问题。但是跑的时间长了,程序复杂了,就会出现问题。就是不想通过实验的方式,而是看看官方有无明确说法。
离线onlyone

只看该作者 4楼 发表于: 2019-09-16
回 汉阳青川 的帖子
汉阳青川:请深入学习理解一下MVC思想 (2019-09-16 10:24) 

我们项目现在还真就是MVC。不过多线程绘图,是为了提高绘图效率。想把每张图放在单独的线程中回去,主线程最后负责贴图显示。就是没看到QT明确说法,子线程能否调用绘图函数。网上结论两边倒,有的说行,有的说不行。
离线onlyone

只看该作者 5楼 发表于: 2019-09-16
既然你用Qt,那么就该明白:所有绘图、显示、界面部分,必须放主线程!对于数据接收,串口也罢、网络tcp也好,你可以在线程操作,当接到一定的数据,然后从线程发信号出来,GUI主线程接收并绘制!你摆好这个架构,再谈CPU与内存!你cpu并不解码、也不做费时算法,能耗那么大,与你框架搭配有显著影响


----以上是摘自一个csdn帖子中的说法。这里是否有明白人,能不能给个官方的说法?
我理解,可以把图像的获取放在子线程中。但是图像的绘制,与显示,必须只能放在主线程中?

离线onlyone

只看该作者 6楼 发表于: 2019-09-16
https://bbs.csdn.net/topics/380244771

这个帖子说的还可以了。QImage 貌似可以在子线程,按照填色的方式绘图。至于能不能使用QImage调用drawline ,估计还是会有问题。
但是 QPixMap 肯定是不能在子线程中绘图的。

在线20091001753

只看该作者 7楼 发表于: 2019-09-16
线程的限制,是指绘制界面的功能,必须在主线程。

QImage,是图片数据,你爱怎么修改,在什么线程修改,都无所谓。

但是将 QImage 的内容,绘制到 widget 上,只能在主线程。
(づ ̄ 3 ̄)づ
离线stlcours

只看该作者 8楼 发表于: 2019-09-16
可能是Windows做的比较牛,或者说Windows容错性比较高(故意这样做),一般情况下在线程里直接操作UI元素也没有问题。有一次我偷懒,就是这么做的,Windows下一直使用没问题,结果同样的代码放到Mac下编译运行,程序直接崩溃!不知道是Mac弱还是Mac严格


结论:不能放到线程里操作UI,就算行也是一时的,就算一直都没有出问题,也只是你运气好,哪天Windows不高兴了,不好意思,分分钟让你崩溃。
离线onlyone

只看该作者 9楼 发表于: 2019-09-17
回 20091001753 的帖子
20091001753:线程的限制,是指绘制界面的功能,必须在主线程。
QImage,是图片数据,你爱怎么修改,在什么线程修改,都无所谓。
但是将 QImage 的内容,绘制到 widget 上,只能在主线程。 (2019-09-16 20:45) 

你这个说法比较靠谱。

我找到官方说法了。

Because QImage is a QPaintDevice subclass, QPainter can be used to draw directly onto images. When using QPainter on a QImage, the painting can be performed in another thread than the current GUI thread.

使用QImage时,可以在子线程中使用QPinter在其上做图。
离线九重水

只看该作者 10楼 发表于: 2019-09-17
画图,分为 1 在界面显示,和 2 在缓存(或显存)绘制两个部分;
界面显示,自然要在主线程;
在缓存绘制,自然哪里都可以。
我曾经做过喷码机,绘制的时候就是‘不在’主线程做的,画完后直接将绘好的画面复制到显示的区域;
如果要用伪代码表示:
dataBuf.xxx操作,各种函数调用,只操作数据;
搞完后,xxx.show,这个show其实就是拷贝画好的画面。
离线icyrat

只看该作者 11楼 发表于: 2019-09-17
是这样的,直接操作ui的函数必须放在主线程的,没什么好讨论的,那个QImage是内寸操作。
快速回复
限100 字节
 
上一个 下一个