1

假设我有多线程我的应用程序。然后根据 Qt 哲学,您甚至无法修改WidgetsGUI 中添加的属性。假设一个类的对象Not_GUI被移动到另一个类QThread,那么在一个函数中调用button1->SetEnabled(false);(在 GUI 中添加)button1是非法的。QPushButtonNot_GUI

目前,我的应用程序有许多 GUI widgets(如 QLabel、QLineEdit 等),并且由于它们events都只在 1 个线程中处理,因此由于大量的绘画活动,应用程序会挂起一段时间。有没有一种方法可以以某种方式将一些工作负载分配Widgets给各个线程?

4

3 回答 3

1

对于第一个示例,使用信号和插槽。QWidget::setEnabled()是一个插槽。创建一个信号modifyWidgetEnableState(bool)并连接到插槽。触发信号而不是使用直接方法调用。

由于大量的绘画活动,应用程序暂停了一段时间

这些小部件是 Qt 内置的吗?如果是,我怀疑挂起是由于绘画。这些小部件是你的吗?那么您可能在子类事件处理程序中进行了太多处理。要做的第一件事是尝试提高您所做的任何事情的性能,第二件事是在线程中移动繁重的处理,并且(再次)使用信号和插槽与小部件进行通信。

编辑:假设 o1 和 o2 并移动到不同的线程 t1 和 t2。

每当o2->slot()作为普通函数调用执行时,它就是正在执行的调用线程slot()。记住,slot()毕竟是一个普通的 C++ 方法。每当触发sig()连接到的信号时,它就是正在执行的接收线程。所以选择一个或另一个,否则你将受到竞争条件的影响。slot()slot()

于 2013-03-14T09:56:19.073 回答
0

正如您所说,Qt 要求所有小部件绘制都在主线程中完成。没有办法解决这个问题。您可以在单独的线程中绘制到 aQImage中,然后只需将图像绘制到其paintEvent(). 但是,首先请记住,这会为所有缓冲区图像占用额外的内存。此外,如果您能够做到这一点,那么在没有线程的情况下采用相同的方法可能会更容易。一般来说,您的目标应该是在内部做尽可能少的工作paintEvent()

于 2013-03-14T09:58:09.037 回答
0

您可以通过调用任何函数从另一个线程修改您的 ui,QMetaObject::invokeMethod()并在您可以使用的单独线程中运行某些函数QtConcurrent::run(我将它与 一起使用QFutureWatcher)。可能不是规范的 Qt 方式,但对我来说很好,如果我不想为每个函数创建自己的 QThread::run

于 2013-03-15T10:54:47.013 回答