1

QMainWindow がアクティブになる前にのみ情報ダイアログを表示した後にクラッシュする、ウィンドウ化されたアプリケーションがあります。

情報ダイアログは、渡されたデータが無効な場合にのみ表示されますが、ユーザーの操作 (ファイルの選択/ドラッグ) または引数として渡された可能性があり、問題が発生する可能性があります。いつ/どのようにエラーダイアログを表示する必要がありますか?

注: ダイアログが (exec() ではなく show() メソッドで) 表示されるだけの場合、クラッシュはしませんが、ダイアログは setModal( true ) を使用してもすぐに破棄されます。

何か案は?ありがとう、

編集:

いくつかのコード:

int WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    QApplication app(__argc, __argv);
    MBViewer viewer;
    viewer.show();
    return app.exec();
}

MBViewer::MBViewer()
{
    setAcceptDrops(true);
    m_ui.setupUi(this);
    m_viewer = new Viewer_Widget();
    m_ui.preview_layout->addWidget(m_viewer);
    parse_parameters();
    connect_controls();
    connect_actions();
}

void MBViewer::connect_controls()
{
    (...)
    connect( m_viewer, SIGNAL( view_initialized()), this, SLOT( open_file() ));
    (...)
}

void MBViewer::open_file()
{
    // somefile is set in parse_parameters or by user interaction
    if (!somefile.is_valid()) { 
        m_viewer->reset();
        // This will crash application after user clicked OK button
        QMessageBox::information( this, "Error", "Error text", QMessageBox::Ok );
        return;
    }
    (...)
}
4

2 に答える 2

1

次の例のように、メイン ウィンドウへのポインターのないメッセージ ボックスを試してください。

QMessageBox msgBox;
msgBox.setText(text.str().c_str());
msgBox.setIcon(QMessageBox::Question);
QPushButton *speed = msgBox.addButton("Speed optimization", QMessageBox::AcceptRole);
QPushButton *memory = msgBox.addButton("Memory optimization", QMessageBox::AcceptRole);
QPushButton *close = msgBox.addButton("Close", QMessageBox::RejectRole);
msgBox.setDefaultButton(speed);
msgBox.exec();
if (msgBox.clickedButton() == memory)
        return true;
if (msgBox.clickedButton() == close)
        exit(4);

ウィンドウを作成する前でも機能します(ただし、QApplicationの初期化後)。

于 2013-05-06T13:55:47.150 に答える
0

app.exec( ) を呼び出すと、ダイアログの表示を開始する前に実行する必要があるメイン メッセージ ハンドラ ループが開始されます。QMessageBox は、exec と一緒に使用するとモーダル ダイアログになるため、app.exec 関数が呼び出されるのを防ぎます。したがって、メッセージ ハンドラーが初期化される前にメッセージが送信され、クラッシュが発生する可能性があります。

show() を使用すると、 app.exec の実行が許可されるため、クラッシュは発生しません。

起動時にモーダル MessageBox が必要な場合は、メッセージ ハンドラーが作成/初期化された後に起動する必要があります。最もクリーンな方法ではありませんが、タイマーで起動して exec の呼び出しを遅らせることができます。

于 2013-05-07T08:29:39.967 に答える