J'ai déjà lu dans un autre sujets que qthreads ne fonctionne pas avec QWidgets [...] mais la sortie dans mon application semble être correcte.
Ce n'est pas correct, sinon vous ne le demanderiez pas, n'est-ce pas? Un QWidget
doit être dans le fil principal. Et c'est probablement le cas. Mais vous invoquez ses méthodes à partir d'un autre thread, et les méthodes que vous invoquez ne sont pas sécurisées par les threads. Ne fais pas ça. Il existe d'autres façons d'invoquer des méthodes en toute sécurité à travers les threads. Utilisez-les à la place. Par exemple, en supposant que vous souhaitez appeler QWidget::resize
, vous pouvez utiliser postToThread
de 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);
Si vous voulez être plus bavard, ou doivent maintenir une base de code Qt 4, vous pouvez le faire à la place:
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);
Les emplacements _d
sont appelés dans le thread du widget. C'est la beauté des connexions automatiques: vous pouvez appeler le signal dans n'importe quel thread, et le slot sera appelé dans le thread de l'objet cible seulement. Comme l'adaptateur est un enfant du widget, il se trouve dans le thread du widget - qui est appliqué par Qt.
Avez-vous essayé de connecter des signaux et des emplacements en utilisant ['Qt :: QueuedConnection'] (http://doc.qt.io/qt-5/qt.html#ConnectionType-enum) ?. En outre, vous ne devez pas utiliser le pointeur sur un QWidget. Utilisez les slots et les signaux pour communiquer le widget entre les threads (encore une fois, pas de pointeurs). Voir l'exemple de [mandelbrot] (http://doc.qt.io/qt-5/qtcore-threads-mandelbrot-example.html) –