Kel*_*inS 1 c++ qt qwidget qthread
我创建了一个QThread类来运行另一个类中的函数,但是另一个类有一个指向QWidget(QwtPlot)的指针,我在应用程序输出中收到此消息:
QCoreApplication::sendPostedEvents: Cannot send posted events for objects in another thread
Run Code Online (Sandbox Code Playgroud)
我已经读过另一个QThreads无法与QWidgets一起使用的主题(UI小部件必须在主线程中),但我的应用程序中的输出似乎是正确的.
任何人都可以向我解释为什么会出现此消息?如果我按原样使用代码会发生什么?
注意:抱歉,我无法发布代码.
提前致谢
我已经读过另一个QThreads不能与QWidgets一起使用的主题[...],但我的应用程序中的输出似乎是正确的.
这不正确,否则你不会问,对吧?
A QWidget必须在主线程中.而且很有可能.但是你从另一个线程调用它的方法,你调用的方法不是线程安全的.不要那样做.还有其他方法可以跨线程安全地调用方法.请改用它们.例如,假设你想打电话QWidget::resize,你可以使用postToThread从这样的回答:
QWidget* widget;
QSize size;
Q_ASSERT_X(widget->thread() == qApp->thread(), "widget",
"The widget must live in the main thread.");
postToThread([=]{ widget->resize(size); }, widget);
Run Code Online (Sandbox Code Playgroud)
如果你想要更详细,或者必须维护Qt 4代码库,你可以这样做:
class TSWidgetAdapter : public QObject {
Q_OBJECT
QWidget * widget() const { return qobject_cast<QWidget*>(parent()); }
Q_SLOT void resize_d(const QSize & size) { widget()->resize(size); }
public:
explicit TSWidgetAdapter(QWidget * parent) : QObject(parent) {
Q_ASSERT_X(parent->thread() == qApp->thread(), "TSWidgetAdapter()",
"The widget must live in the main thread.");
connect(this, SIGNAL(resize(QSize)), this, SLOT(resize_d(QSize)));
}
Q_SIGNAL void resize(const QSize & size);
};
QWidget* widget;
QSize size;
TSWidgetAdapter widget_ts(widget);
widget_ts.resize(size);
Run Code Online (Sandbox Code Playgroud)
该_d插槽称为widget的线程.这就是自动连接的美妙之处:您可以在任何线程中调用信号,并且仅在目标对象的线程中调用插槽.由于适配器是小部件的子代,因此它位于小部件的线程中 - 由Qt强制执行.
| 归档时间: |
|
| 查看次数: |
1404 次 |
| 最近记录: |