1

我有一个窗口应用程序,仅在激活 QMainWindow 之前显示信息对话框后崩溃。

仅当传递的数据无效时才会显示信息对话框,但它可能是用户交互(文件选择/拖动)或作为参数传递,这会导致问题。何时/如何显示此类错误对话框?

注意:当只显示对话框时(使用 show() 方法而不是 exec())它不会崩溃,但即使使用 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 回答