2

開始後に静的関数を呼び出す新しいスレッドを作成したとします。その静的関数内で、カスタム qdialog を作成して表示する必要があります。親がなく、適切なスレッドに配置されるようにするには、どうすれば作成できますか?

コンストラクターは親を 0 に設定しますが、別のスレッドで親の子を作成できないというエラーが引き続き報告されます。これは静的関数であるため、「this」オブジェクトを使用できず、「this」がないと現在のスレッドまたはスレッド ID を取得できません。myCustomDialog->moveToThread() を呼び出すことができると思いましたが、静的関数から正しいスレッドを決定する方法がわかりません。

QMessageBox 静的関数の 1 つを使用すると、すべて正常に動作します。たとえば、 QMessageBox::information(0, tr("Title"), tr("Message")) を呼び出してもエラーは報告されません。カスタム qdialog をコーディングして、qmessagebox 静的関数と同様に機能させるにはどうすればよいですか?

qApp オブジェクトから実行中のすべてのスレッドのリストを取得する方法はありますか? 他の提案はありますか?

static int myFunction();

int myObject::myFunction()
{
    myCustomDialog *mcd = new myCustomDialog();
    // as soon as I call exec() it reports an error and crashes
    mcd->exec();
    // QObject: Cannot create children for a parent that is in a different thread.

    // can't call mcd->moveToThread() without knowing the current thread
    // how can I determine the current thread from this static function?
    // if parent = 0 then why is this error occurring?
    return 0;
}

myCustomDialog(QWidget *parent = 0);

myCustomDialog::myCustomDialog(QWidget *parent) : QDialog(parent)
{
    // create widgets and layout here
}
4

2 に答える 2

2

しないでください。別のスレッドから QWidget オブジェクトを作成するのは悪い考えです。ドキュメントには次のように記載されています。

GUI アプリケーションでは、GUI 関連の操作を実行できる唯一のスレッドであるため、メイン スレッドは GUI スレッドとも呼ばれます。

私が通常これを回避する方法は、メイン スレッド (多くの場合、私にとっては MainWindow) に存在するオブジェクトに接続されている非 GUI スレッドでオブジェクトからシグナルを送信することです。受信オブジェクトは、メイン スレッドでダイアログを作成します。

他の回答で述べたように、この接続は、接続タイプをQt::BlockingQueuedConnectionとして確立することにより、必要に応じてワーカー スレッドをブロックできます。

他のスレッドから関数を呼び出す方法の詳細については、この投稿を参照してください。

于 2013-07-31T00:03:20.527 に答える