假设我的应用程序有多线程。那么按照Qt哲学,你甚至无法修改GUI中添加的Widgets
的属性。假设班级Not_GUI
的对象已移至另一个QThread
,则调用button1->SetEnabled(false);
(button1
是GUI中添加的QPushButton
)非法Not_GUI
的功能。
目前我的应用程序有许多GUI widgets
(如QLabel,QLineEdit等)&由于所有events
仅在1个线程中处理,因此应用程序会因为巨大的绘画活动而挂起一段时间。
有没有办法以某种方式将Widgets
的一些工作量分配给各种线程?
答案 0 :(得分:1)
对于第一个示例,使用信号和插槽。 QWidget::setEnabled()
是一个广告位。创建信号modifyWidgetEnableState(bool)
并连接到插槽。触发信号而不是使用直接方法调用。
由于巨大的绘画活动,应用程序暂停了一段时间
这些小部件Qt是否内置?如果是的话,我怀疑挂起是由于这幅画。这些小部件是你的吗?然后,您可能在子类事件处理程序中进行了太多处理。 首先要做的是尝试提高你所做的任何事情的性能,第二件事就是在线程中移动繁重的处理,然后(再次)使用信号和插槽与小部件。
编辑: 假设o1和o2被移动到不同的线程t1和t2。
每当o2->slot()
作为普通函数调用执行时,它就是执行slot()
的 调用线程 。请记住,slot()
毕竟是一个普通的C ++方法。每当触发与sig()
连接的信号slot()
时,正在执行slot()
的 接收方线程 。因此,请选择其中一个,否则您将受到竞争条件的影响。
答案 1 :(得分:0)
正如你所说,Qt要求所有小部件绘画都在主线程中完成。没有办法解决这个问题。您可以在单独的线程中绘制到QImage
,然后只需将图像绘制到其paintEvent()
中的窗口小部件中。但是,首先请记住,这会占用所有缓冲区图像的额外内存。此外,如果您能够做到这一点,那么在没有线程的情况下采用相同的方法可能会更容易。一般来说,您的目标应该是在paintEvent()
内尽可能少地完成工作。
答案 2 :(得分:0)
您可以调用任何函数来通过QMetaObject::invokeMethod()
从另一个线程修改您的ui,并在单独的线程中运行某些函数,您可以使用QtConcurrent::run
(我将其与QFutureWatcher
一起使用)。可能不是规范的Qt方式,但对我来说就好了,如果我不想为每个函数创建我自己的QThread :: run