2015-11-09 5 views
3

Главное окно моего приложения Qt - это нормальный подкласс QMainWindow. В этом окне у меня есть несколько кнопок; каждый из них имеет свой clicked сигнал подключен свой собственный слот, и каждый слот создает различные QDialog как так:Вызывает ли вызов QDialog :: exec в слот-блоке цикл основного события?

void onButtonA_clicked() 
{ 
    MyADialog* dialog = new MyADialog(this); 
    dialog->exec(); 
    delete dialog; 
} 

Я читал эту статью: https://wiki.qt.io/Threads_Events_QObjects#Events_and_the_event_loop и автор говорит

вы никогда не должны когда-либо заблокировать контур события

, который меня заинтересовал; exec является блокирующей функцией, поэтому согласно тому, что он там говорит (его пример с Worker::doWork, который выполняет большую работу и требует некоторого времени для завершения), мой код блокирует цикл событий, но я не заметил ничего, что могло бы предложить это; напротив, главное окно, похоже, ведет себя нормально, и не было никакой разницы, когда я изменил код, чтобы использовать метод show().

Я блокирую цикл событий? Должен ли я использовать другой подход здесь?

+0

Насколько я знаю, 'int QDialog :: exec()' не блокирует приложение Qt, а только родительское окно, и только если диалог является модальным. – Tarod

+0

@Tarod Ну, это блокирующая функция (в том, что она не возвращается, пока QDialog не закрыт), поэтому я не уверен. – szczurcio

ответ

8

QDialog :: exec() блокирует цикл основного события, да. Он не блокирует пользовательский интерфейс, поскольку он открывает локальный цикл событий внутри exec(), который обрабатывает события во время открытия диалога. Это может быть источником неприятных ошибок: (Почти) все может произойти до того, как exec() вернется, внешние события (таймеры, сеть, IPC, что угодно) могут вызывать слоты, вызывать другие диалоги и т. Д. Просто способы для пользователя делать неожиданные вещи напрямую обычно ограничены, учитывая модальность большинства таких диалогов.

Необходимо знать о возможной проблеме и не оставлять приложение в несогласованном состоянии при вызове функции exec() и не полагаться на то, что должно быть так, как было потом.

В качестве альтернативы позвоните неблокируемому QDialog::open() и подключитесь к сигналу finished().

+1

Теперь все ясно, спасибо. – szczurcio

+0

Очень хорошее объяснение! Благодарю. – Tarod

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

  • Нет связанных вопросов^_^