将 QGridLayout::addWidget 与 mutythread 一起使用
use QGridLayout::addWidget with mutythread
由于创建小部件需要花费大量时间,我尝试在不同的线程中创建小部件并将它们添加到主布局中,但是失败了。创建小部件然后按顺序添加它们时,程序正常运行。我收到的通知:"QObject::setParent: Cannot set parent, new parent is in a different thread"
有办法吗?
不行,没有办法。
Qt GUI 类 包括 QWidget
必须只能从主线程使用。
引用 Qt documentation:
Although QObject is reentrant, the GUI classes, notably QWidget and
all its subclasses, are not reentrant. They can only be used from the
main thread. As noted earlier, QCoreApplication::exec() must also be
called from that thread.
当您构造 QWidget
:
时,Q_ASSERT_X
在 Qt 代码中强制执行此操作
Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget",
"Widgets must be created in the GUI thread.");
因此,即使您找到一些变通办法使其工作,您也无法保证您的代码将以可重现的方式工作,并且任何 Qt 更新都不会破坏您的代码。
关于您的具体问题,创建小部件应该不会耗费时间。我能想到这会很耗时的两个原因:
- 您的小部件在创建时会进行大量计算。然后你应该把计算,而且只放在另一个线程中。
- 您一次创建了很多小部件。您可以使用事件循环推迟创建。基本上,您创建一些小部件,然后 post 一个事件或设置一个计时器来创建更多小部件,等等,直到您满足一些停止条件。
由于创建小部件需要花费大量时间,我尝试在不同的线程中创建小部件并将它们添加到主布局中,但是失败了。创建小部件然后按顺序添加它们时,程序正常运行。我收到的通知:"QObject::setParent: Cannot set parent, new parent is in a different thread" 有办法吗?
不行,没有办法。
Qt GUI 类 包括 QWidget
必须只能从主线程使用。
引用 Qt documentation:
Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread. As noted earlier, QCoreApplication::exec() must also be called from that thread.
当您构造 QWidget
:
Q_ASSERT_X
在 Qt 代码中强制执行此操作
Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget",
"Widgets must be created in the GUI thread.");
因此,即使您找到一些变通办法使其工作,您也无法保证您的代码将以可重现的方式工作,并且任何 Qt 更新都不会破坏您的代码。
关于您的具体问题,创建小部件应该不会耗费时间。我能想到这会很耗时的两个原因:
- 您的小部件在创建时会进行大量计算。然后你应该把计算,而且只放在另一个线程中。
- 您一次创建了很多小部件。您可以使用事件循环推迟创建。基本上,您创建一些小部件,然后 post 一个事件或设置一个计时器来创建更多小部件,等等,直到您满足一些停止条件。