在Qt中修改非GUI线程中的小部件?

时间:2013-03-14 09:13:49

标签: performance qt qthread

假设我的应用程序有多线程。那么按照Qt哲学,你甚至无法修改GUI中添加的Widgets的属性。假设班级Not_GUI的对象已移至另一个QThread,则调用button1->SetEnabled(false);button1是GUI中添加的QPushButton)非法Not_GUI的功能。

目前我的应用程序有许多GUI widgets(如QLabel,QLineEdit等)&由于所有events仅在1个线程中处理,因此应用程序会因为巨大的绘画活动而挂起一段时间。 有没有办法以某种方式将Widgets的一些工作量分配给各种线程?

3 个答案:

答案 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