0

SBC6000x ボードで Qt アプリケーション (Qt バージョン 4.7.3) を開発しています。

QDialog から派生した MessageBox クラスがあります。このクラスをシングルトンにしました。

メッセージボックスを表示するときはいつでも、.exec メソッドを使用して表示しています。

メッセージボックスを次々に表示する必要がある場所はほとんどありません。

したがって、新しいメッセージ ボックスを表示するには、前のメッセージ ボックスを閉じて新しいメッセージ ボックスを表示する必要があります。

たとえば、メッセージボックスが開いていると同時にバックグラウンドからエラーが発生した場合、現在表示されているメッセージボックスを閉じて、エラーのあるメッセージボックスを表示する必要があります。

前のダイアログを閉じるために、メッセージ ボックス クラスから CloseDlg メソッドを公開し、それを閉じようとしました。

この CloseDlg 内で、完了信号を発しています。

void CMsgBox::CloseDlg()
{
    if (NULL != CMsgBox::m_msgBox)
    {
        if(CMsgBox::m_msgBox->isVisible())
        {
            emit CMsgBox::m_msgBox->finished(0);
            //QApplication::processEvents();
        }
    }
}

そしてそれを

CMsgBox::CloseDlg();

私の表示方法は次のとおりです:-

int CMsgBox::showMsgBox(Icon icon, const QString &textMsg, const QString &okBtnText)
{
    if (CMsgBox::m_msgBox == NULL)
    {
        CMsgBox::m_msgBox = new CMsgBox();
    }
    CMsgBox::m_msgBox->setText(textMsg);
    CMsgBox::m_msgBox->setIcon(icon);
    CMsgBox::m_msgBox->setOkBtnText(okBtnText);
    CMsgBox::m_msgBox->exec();

    return CMsgBox::m_msgBox->m_btnPressed; //return, unblock the call
}

再び showMsgBox を呼び出すと、次の警告が表示されます。QDialog::exec: 再帰呼び出しが検出されました

問題は、前の exec 呼び出しから戻らないことです (上記の // にコメントしたように、戻らない限り)。

finished() イベントの代わりに close()、accept()、reject() メソッドで同じことを試みましたが、何も機能しませんでした。

前のexe呼び出しから戻り、上記のシナリオを達成する方法は何ですか? どんな助けでも大歓迎です。

4

3 に答える 3

1

ここにあるものは、競合状態のように見えます。モーダル QDialog は独自のイベント ループを実行するため、アプリケーションはマルチスレッド アプリケーションのように動作し、並行性と競合状態に注意する必要があります。

メイン イベント ループで 1 秒を受け取ると、すばやく連続してCMsgBox::CloseDlg()andを呼び出します。CMsgBox::showMsgBox()ただし、CloseDlg()ダイアログのイベント ループに戻るように指示しますが、CloseDlg()実際には、ダイアログのイベント ループのクリーンアップが完了する前に戻り、まだ終了していないダイアログをshowMsgBox()呼び出そうとします。exec()

あなたがする必要があるのは、 を呼び出すときに信号CMsgBox::CloseDlg()に接続し、finished(int)を受け取ったときにのみ安全にダイアログを再度表示finished(int)できることです。exec()

注: 信号に接続するときは、デフォルトの a の代わりにfinished(int)必ず a を使用してください。Qt::QueuedConnectionQt::DirectConnection

于 2012-12-11T18:16:45.823 に答える
0

したがって、モードレス ダイアログ ボックスが必要です。ドキュメントで説明されているように:

モードレス ダイアログは、show() を使用して表示されます。これは、制御を呼び出し元にすぐに返します。

したがって、ボックスをexec()で表示する代わりに、 で表示しますshow()

于 2012-12-11T09:18:00.247 に答える
0

別の回答で提案されている show() メソッドの代替は、を使用することQDialog::open()です。戻りますが、モーダル ダイアログが表示されるため、閉じるまで残りの GUI は無効になります。

于 2012-12-11T09:22:46.127 に答える