Как предотвратить вызов двойного слота при отображении QMessageBox?

Я подключил сигнал editFinished QLineEdit к слоту в моем приложении, показывающему QMessageBox, если ввод каким-то образом неожиданный. Как ни странно, окно сообщения отображается дважды, поэтому я поставил точку останова там, где оно выполняется, и посмотрел на трассировку стека. Там QMessageBox.exec() вызывает QApplication::processEvents(), который каким-то образом пересылает и снова обрабатывает одно и то же событие.

Моя трассировка стека в первый раз выглядит так:

MyApp::mySlot()
QLineEdit::editingFinished()
QGuiApplicationPrivate::processMouseEvent()
QEventLoop::processEvents()
QApplication::exec()

и второй раз так:

MyApp::mySlot()
QLineEdit::editingFinished()
QGuiApplicationPrivate::processWindowSystemEvent()
QEventLoop::processEvents()
QDialog::exec()
// stack trace of run #1 here
// [...]

Я уже проверил наличие двойных сигнальных соединений или различных событий, связанных с этим слотом, но, похоже, это не проблема. Может кто-нибудь объяснить, что здесь происходит и как это предотвратить?


person user1709708    schedule 22.04.2015    source источник


Ответы (1)


Это ошибка Qt, когда editFinished генерируется дважды, вы можете прочитать об этом здесь:

https://forum.qt.io/topic/39141/qlineedit-editingfinished-signal-is-emitted-twice

Также описан обходной путь.

if(lineEdit->text().toDouble()<1000) {
lineEdit->blockSignals(true);
QMessageBox::information(this, "Information", "Incorrect value");
lineEdit->blockSignals(false);
}
person demonplus    schedule 22.04.2015
comment
Да, спасибо. Если я использую returnPressed(), он выполняется только один раз. К сожалению, обходной путь с блокировкой и разблокировкой сигналов до и после показа MBox не работает, тогда как для всех остальных он работает. - person user1709708; 22.04.2015
comment
Если обходной путь не работает для вас, можете ли вы обработать focusOutEvent и returnPressed? Вместе они должны быть похожи на editFinished. - person demonplus; 22.04.2015
comment
Я наконец нашел проблему. Несколько QLineEdits были подключены к одному слоту updateAll. Затем, когда я украл фокус у одного QLineEdit, обычно нажимая TAB, курсор перескакивал на другой QLineEdit, подключенный к тому же слоту. Это означает, что ввод проверки слота выполнялся для QLineEdit, выбранного первым, потенциально показывал QMessageBox, который снова украл фокус у второго QLineEdit, находящегося в фокусе в данный момент, и, таким образом, приводил к выполнению второго слота. Интересно, что теперь он даже работает без каких-либо обходных путей. - person user1709708; 23.04.2015