无法在另一个线程-QT中向对象发送已发布的事件

Cannot send posted events for objects in another thread - Qt

本文关键字:事件 对象 另一个 线程 -QT      更新时间:2023-10-16

我已经创建了一个 qthread 类来运行另一个类中的函数,但是这另一个类有一个指向 qwidget (qwtplot),我在应用程序输出中收到此消息:

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

我已经在另一个主题中阅读了Qthreads与Qwidgets不起作用(UI小部件必须在主线程中),但是我的应用程序中的输出似乎是正确的。

谁能向我解释为什么会出现此消息?如果我让代码原样会发生什么?

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

预先感谢

我已经阅读了另一个主题,即Qthreads与qwidgets不起作用[...] 但是我的应用程序中的输出似乎是正确的。

这是不正确的,否则您不会问,对吗?

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

如果您想变得更详细,或者必须维护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。

强制执行。