2013-05-06 2 views
1

У меня есть оконное приложение, которое разбивается после отображения диалогового окна информации только до активации QMainWindow.Показать диалоговое окно перед основным окном

Диалог информации отображается только в том случае, если переданные данные недействительны, однако это может быть взаимодействие с пользователем (выбор/перетаскивание файла) или передача в качестве аргумента, что вызывает проблемы. Когда/как я должен показывать такой диалог ошибок, чем?

Примечание: Когда диалог отображается только (с помощью метода show(), а не exec()), он не сбой, но диалог сразу же отбрасывается даже с помощью setModal (true).

Любые идеи? Спасибо,

EDIT:

Некоторый код:

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; 
    } 
    (...) 
} 
+2

Пожалуйста, разместите самодостаточный компилируемый пример, который воспроизводит проблему ... –

+1

'show()' является асинхронным (вызов немедленно возвращается) и 'exec()' является синхронным (вызов ждет, когда диалог будет закрыт). Может быть, это помогает? – leemes

ответ

0

Когда вы вызываете app.exec(), он запускает цикл обработки основного сообщения, который должен быть запущен до начала отображения диалогов. QMessageBox - это модальный диалог при использовании с exec, поэтому это предотвратит вызов функции app.exec. Поэтому, вероятно, сообщения отправляются до того, как обработчик сообщений был инициализирован, и поэтому наблюдается сбой.

Когда используется show(), выполнение app.exec позволяет обрабатывать, поэтому авария не происходит.

Если вы хотите создать modal MessageBox при запуске, вам необходимо запустить его после создания/инициализации обработчика сообщений. Не самый чистый способ, но вы можете попробовать запустить его на таймере, чтобы задержать вызов exec.

+0

Вот что я подозревал. Спасибо за разъяснение. Есть ли какой-либо чистый способ (сигнал), который отмечает, что основной цикл сообщений запущен? –

+0

Не то, что я знаю, но если вы MBViewer выведен из QMainWindow, вы можете перегрузить функцию showEvent (QShowEvent *), чтобы увидеть, когда отображается главное окно. – TheDarkKnight

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).

+0

Да, я уже пробовал аналогичный подход, есть еще проблема, когда пользователь заканчивает диалог, что приводит к сбою. –

+0

И вы инициализировали msgBox без родителя? Вероятно, тогда вам нужно отправить отчет об ошибке в проект Qt. – ypnos

+0

Да, я также пробовал инициализацию без родителя? Все равно никаких изменений. Спасибо, в любом случае. –

Смежные вопросы