无法发送发布的事件在另一个线程对象 - Qt的

问题描述:

我创建了一个的QThread类运行一个函数,在另一个类,但是这另一个类有一个指向QWidget的(QwtPlot),和我我在应用程序的输出接收到此消息:无法发送发布的事件在另一个线程对象 - Qt的

QCoreApplication::sendPostedEvents: Cannot send posted events for objects in another thread 

我已经在另一个话题读取QThreads不QWidgets(UI部件必须在主线程)工作,但在我的应用程序的输出似乎是正确的。

任何人都可以向我解释为什么这条消息出现?如果我让代码保持原样,会发生什么?

注意:对不起,我无法发布代码。

在此先感谢

+0

您是否尝试过使用['Qt :: QueuedConnection'](http://doc.qt.io/qt-5/qt.html#ConnectionType-enum)?连接信号和插槽?另外,你不应该使用指向QWidget的指针。使用插槽和信号在线程之间传递小部件(再次,无指针)。请参阅[mandelbrot示例](http://doc.qt.io/qt-5/qtcore-threads-mandelbrot-example.html) –

我已经在另一个话题读取QThreads不QWidgets工作[...] 但在我的应用程序的输出似乎是正确的。

这是不正确的,否则你不会问,对吧?

A QWidget必须在主线程中。最有可能的是。但是你从另一个线程调用它的方法,并且你调用的方法不是线程安全的。不要这样做。还有其他方法可以跨线程安全地调用方法。改用它们。例如,假设你想打电话QWidget::resize,你可以使用postToThreadthis answer

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); 

如果您想更详细,还是要保持一个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); 

_d插槽在小部件的线程中被调用。这就是自动连接的优点:您可以在任何线程中调用该信号,并且该槽将仅在目标对象的线程中调用。由于适配器是小部件的子项,它在小部件的线程中 - 这是由Qt强制执行的。