我已經在另一個話題讀取QThreads不QWidgets工作[...] 但在我的應用程序的輸出似乎是正確的。
這是不正確的,否則你不會問,對吧?
A QWidget
必須在主線程中。最有可能的是。但是你從另一個線程調用它的方法,並且你調用的方法不是線程安全的。不要這樣做。還有其他方法可以跨線程安全地調用方法。改用它們。例如,假設你想打電話QWidget::resize
,你可以使用postToThread
從this 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強制執行的。
您是否嘗試過使用['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) –