処理用のスレッドと可変量のウィンドウ インスタンスの両方を必要とするクライアント アプリケーションを QT で作成しようとしています。しかし、処理スレッドの 1 つの中に新しいウィンドウを作成する方法を見つけようとして苦労しています。すべての ui 要素を QApplication クラスと同じスレッドで作成する必要があることは理解していますが、インスタンス化できる必要があるか、少なくとも別のスレッドで QDialog への参照が必要です。
スレッドと QDialog の間の通信はシグナルを使用して行うことができます。これについては心配していませんが、実際にウィンドウを作成することは別の問題です。シグナルを使用して、ウィンドウへのインスタンスを作成するようメイン スレッドに指示し、そのインスタンスへのポインターを何らかの方法で取得することもできますが、それは少し複雑で見苦しく思えます。そのようなタスクを達成するためのより良い方法はありますか? メインスレッドの外でQDialogを作成するには、QApplicationクラスが存在していましたか?
編集: Q_INVOKABLE メソッドを試しましたが、複数のスレッドで機能しません。指定したタイプの QDialog を作成し、それへのポインタを返すビュー ファクトリ クラスを作成しました。このクラスはメイン GUI スレッドでインスタンス化され、このクラスへの参照がすべてのワーカー スレッドに送信されます。問題は、スレッドが Qt::BlockingQueuedConnection を使用してファクトリから create メソッドを呼び出すと、invoke メソッドが失敗することです。Qt::DirectConnection に変更すると、invoke メソッドは正しい create メソッドを呼び出しますが、現在のスレッドではワーカー スレッドとして呼び出されます。
私の主な機能は次のようになります:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ViewFactory vFactory;
vFactory.registerCreator(Util::W_CONNECT, new ConnectWindow::ConnectCreator());
ClientApp app;
if(!app.Initialize(&vFactory))
return 0;
app.start();
a.exec();
.............................
}
そして、ClientApp スレッドからの実行関数は次のようになります。
void ClientApp::run()
{
QDialog * tmp = NULL;
QMetaObject::invokeMethod(this->_vFactory, "create", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(QDialog*, tmp), Q_ARG(int, 0));
}
私が言ったように、接続タイプを Qt::DirectConnection に変更しても、invokeMothod は失敗しないため、params は問題ではなく、別のワーカー スレッドでメソッドを呼び出します。