在Qt中修改非GUI线程中的小部件?
假设我有多线程应用程序。然后根据Qt哲学,您甚至不能修改在GUI中添加的Widgets
的属性。假设类别Not_GUI
的对象已被移动到另一个QThread
,那么在Not_GUI
的函数中调用button1->SetEnabled(false);
(button1
是添加在GUI中的QPushButton
)是非法的。在Qt中修改非GUI线程中的小部件?
目前我的应用程序有许多GUI widgets
(如QLabel,QLineEdit的,等等)&,因为所有的events
只有1线程的应用程序挂起了一阵处理,由于巨大的绘画活动。 有没有办法让我可以以某种方式将Widgets
的一些工作量分配给各种线程?
第一个例子使用信号和插槽。 QWidget::setEnabled()
是一个插槽。创建一个信号modifyWidgetEnableState(bool)
并连接到插槽。触发信号而不是使用直接方法调用。
应用程序挂起了一会儿,由于巨大的绘画活动
难道这些小部件的Qt构建?如果是的话,我怀疑这是因为这幅画的缘故。这些小工具是你的吗?那么你可能在你的子类事件处理器中做了太多的处理。要做的第一件事就是尝试提高你所做的任何事情的性能,第二件事是在线程中移动繁重的处理,并且(再次)使用信号和插槽与小部件进行通信。
编辑: 假设o1和o2并被移动到不同的线程t1和t2。
每当o2->slot()
被作为正常的函数调用执行则它是调用线程正在执行slot()
。记住,slot()
毕竟是一个正常的C++方法。每当连接到slot()
的信号被触发,则它是接收线程正在执行slot()
。所以选择一个或另一个,否则你将受到竞争条件。
正如你所说,Qt要求在主线程中完成所有的widget绘制。这是没有办法的。您可以在一个单独的线程中将可以涂成QImage
,然后只需将图像绘制到其小部件paintEvent()
中。但是,首先要记住,这会占用所有缓冲图像的额外内存。另外,如果你能够做到这一点,那么采用相同的方法而不用线程就可能更容易。一般而言,您的目标应该是在paintEvent()
内尽可能少地完成工作。
你可以调用任何函数来通过QMetaObject::invokeMethod()
从另一个线程修改你的UI,并在可以使用QtConcurrent::run
(我与QFutureWatcher
一起使用它)的单独线程中运行某个函数。可能不是规范的Qt方式,但对我来说很好,如果我不想为每个函数创建我自己的QThread ::运行
关于SIGNAL&SLOT ans: SLOT上的处理是否完成GUI线程或SIGNAL发出的线程? 是的小部件只是Qt构建我还没有创建任何自定义小部件。使用像QLabel,QLineEdit这样的小部件。挂起是由于绘画只是因为如果我不添加该QGridLayout到GUI然后没有挂起。通过挂断我的意思是,应用程序不响应点击和显示(没有响应)和Windows 7中的圆形光标。 我没有处理任何事件我自己。一切都由Qt的功能来处理。 – 2013-03-14 10:21:44
如果'o1'和'o2'被***移动到***不同线程't1'和't2','o1'触发信号,那么'o2'的槽将由线程't2执行'。如果你直接调用'o2-> slot()',那么它将像任何正常的函数调用一样被执行。但是这是多线程的问题。 – UmNyobe 2013-03-15 09:09:29
这个坑不是由于绘画。无限期地不。这是由于你的函数在主线程中做了大量的处理,这会妨碍显示画图代码的执行。 – UmNyobe 2013-03-15 09:11:39