ich in einem anderen Themen schon gelesen, dass QThreads nicht mit QWidgets funktioniert [...] aber die Ausgabe in meiner Anwendung scheint korrekt zu sein.
Es ist nicht korrekt, sonst würden Sie nicht fragen, oder?
Ein QWidget
muss im Hauptthread sein. Und wahrscheinlich ist es das auch. Aber Sie rufen seine Methoden aus einem anderen Thread auf, und die Methoden, die Sie aufrufen, sind nicht Thread-sicher. Tu das nicht. Es gibt andere Möglichkeiten, Methoden sicher über Threads hinweg aufzurufen. Benutze sie stattdessen. Wenn zum Beispiel angenommen, dass Sie wünschen QWidget::resize
rufen Sie postToThread
von this answer verwenden:
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);
Wenn Sie ausführlichere sein wollen oder müssen, um einen Qt 4-Code halten Basis, könnten Sie diese stattdessen tun:
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);
Die _d
Slots werden im Thread des Widgets aufgerufen. Das ist das Schöne an automatischen Verbindungen: Sie können das Signal in einem beliebigen Thread aufrufen, und der Slot wird nur im Thread des Zielobjekts aufgerufen. Da der Adapter ein Kind des Widgets ist, befindet es sich im Thread des Widgets - das wird von Qt erzwungen.
Haben Sie versucht, Signale und Steckplätze mithilfe von ['Qt :: QueuedConnection'] (http://doc.qt.io/qt-5/qt.html#ConnectionType-enum) zu verbinden ?. Außerdem sollten Sie den Zeiger nicht auf ein QWidget verwenden. Verwenden Sie Slots und Signale, um das Widget zwischen Threads zu kommunizieren (auch hier keine Zeiger). Siehe das [Mandelbrot-Beispiel] (http://doc.qt.io/qt-5/qtcore-threads-mandelbrot-example.html) –