Как программно вернуться из метода exec в статический синглтон-класс

Я занимаюсь разработкой приложения Qt (версия 4.7.3 Qt) на плате SBC6000x.

У меня есть класс MessageBox, полученный из QDialog. Я сделал этот класс синглтон.

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

Есть несколько мест, где мне нужно показывать почтовые ящики один за другим.

Итак, чтобы показать новое окно сообщения, я должен закрыть предыдущее и показать новое.

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

Чтобы закрыть предыдущее диалоговое окно, я выставил метод CloseDlg из класса messagebox и пытался закрыть его.

Внутри этого CloseDlg я излучаю законченный сигнал.

void CMsgBox::CloseDlg()
{
if (NULL != CMsgBox::m_msgBox)
{
if(CMsgBox::m_msgBox->isVisible())
{
emit CMsgBox::m_msgBox->finished(0);
//QApplication::processEvents();
}
}
}

и называя это как

CMsgBox::CloseDlg();

Мой метод показа:

int CMsgBox::showMsgBox(Icon icon, const QString &textMsg, const QString &okBtnText)
{
if (CMsgBox::m_msgBox == NULL)
{
CMsgBox::m_msgBox = new CMsgBox();
}
CMsgBox::m_msgBox->setText(textMsg);
CMsgBox::m_msgBox->setIcon(icon);
CMsgBox::m_msgBox->setOkBtnText(okBtnText);
CMsgBox::m_msgBox->exec();

return CMsgBox::m_msgBox->m_btnPressed; //return, unblock the call
}

Снова, когда я вызываю showMsgBox, он показывает мне следующее предупреждение.
QDialog :: exec: обнаружен рекурсивный вызов

Проблема в том, что он не возвращается из предыдущего вызова exec (если мы не вернемся, как прокомментировано выше //).

Я пробовал то же самое с методами close (), accept (), reject () вместо события finish (), но ничего не получалось.

Как можно вернуться с предыдущего exe-вызова и достичь вышеописанного сценария? Любая помощь приветствуется.

0

Решение

То, что у вас здесь, выглядит как состояние гонки. Модальный QDialog запускает собственный цикл обработки событий, поэтому ваше приложение ведет себя как многопоточное приложение, и вам нужно позаботиться о параллелизме и условиях гонки.

Когда вы получаете секунду в вашем основном цикле событий, вы звоните CMsgBox::CloseDlg() а также CMsgBox::showMsgBox() в быстрой последовательности. Тем не мение, CloseDlg() говорит циклу событий диалога вернуться, но CloseDlg() фактически возвращается до очистки цикла событий диалога, и showMsgBox() попытки позвонить exec() в диалоге, который еще не завершен.

Что вам нужно сделать, это когда вы звоните CMsgBox::CloseDlg(), подключитесь к finished(int) сигнал, и только когда вы получаете finished(int) ты можешь безопасно exec() снова диалог

ПРИМЕЧАНИЕ. При подключении к finished(int) сигнал, обязательно используйте Qt::QueuedConnection вместо Qt::DirectConnection который по умолчанию.

1

Другие решения

Итак, вам нужно немодальное диалоговое окно. Как объяснено в их документации:

Немодальные диалоги отображаются с помощью show (), который немедленно возвращает управление вызывающей стороне.

Поэтому вместо того, чтобы показывать окно с exec(), покажи это с show(),

0

Альтернатива методу show (), предложенному в другом ответе: QDialog::open(). Он вернется, но все равно выдаст вам модальное диалоговое окно, поэтому остальная часть графического интерфейса будет отключена, пока вы не закроете его.

0
По вопросам рекламы [email protected]