没有双重/同时只有一个 QMessageBox
No double / Only one QMessageBox at same time
在我的申请中,我有以下情况:
- 在
QTabWidget
输入的验证方法中,我要确定子小部件输入的错误。
- 因此我将此子小部件设置为活动小部件
- 在这个小部件的
showEvent
中,我将 QTimer::singleShot
触发到方法 onShowEventFinished()
中,我将在其中显示 QMessageBox
- 激活新的子小部件后,我想首先显示来自验证(步骤 1)的错误消息。
然后来自验证的消息出现了,但是由于我在第 3 步中的 singleShot,另一个出现在它上面。我想在第一个关闭时最早显示第二个。
(重要的是,第一条消息最早会在相关子小部件显示时出现。)
示例代码:
class MySubwidget : public QWidget
{
// omitted (ctor, etc.)
protected:
void showEvent( QShowEvent* e )
{
QShowEvent( e );
QTimer::singleShot( 200, this, SLOT(onShowEventFinished()) );
};
private slots:
void onShowEventFinished()
{
bool showEntryHint = false;
// omitted (some stuff to determine to show an entry hint or not)
if( showEntryHint )
{
QMessageBox t_MessageBox( this );
// omitted (set up the message box
t_MessageBox.exec();
}
};
};
我尝试了不同的方法来解决这个问题,在 QMessageBox
派生的 class 中使用 QMutex
、QWaitCondition
或 QSemaphore
,但这没有无法正常工作,因为消息框的执行在同一个线程中。
这意味着,当第一个消息框以 QMessageBox::exec()
开始时,QApplication::processEvents
(由 QMessageBox
调用)导致调用我的插槽并调用 QMessageBox::exec()
两次(对于第二个提示,第一个 exec()
一直存在,直到第一个消息框关闭)。
我目前的解决方法是在显示 MyMessageBox
的另一个实例时调用 QApplication::processEvents()
的子 class:
class MyMessageBox : public QMessageBox
{
public:
// omitted (ctor, etc.)
int exec()
{
while( MessageBoxShowingCount > 0 )
QApplication::processEvents();
return QMessageBox::exec();
};
protected:
void showEvent( QShowEvent* e )
{
MessageBoxShowingCount++;
QMessageBox::showEvent(e);
};
void hideEvent( QHideEvent* e )
{
QMessageBox::hideEvent(e);
MessageBoxShowingCount--;
};
static int MessageBoxShowingCount = 0;
};
(对于此解决方案,我已将所有 QMessageBox
-实例替换为 MyMessageBox
-实例。)
您似乎需要的是一个应用程序范围的消息管理器。 QMessageBox
然后成为 class 的实现细节,不再直接使用。当您想显示消息时,您可以使用 MessageManager
class.
在我的申请中,我有以下情况:
- 在
QTabWidget
输入的验证方法中,我要确定子小部件输入的错误。 - 因此我将此子小部件设置为活动小部件
- 在这个小部件的
showEvent
中,我将QTimer::singleShot
触发到方法onShowEventFinished()
中,我将在其中显示QMessageBox
- 激活新的子小部件后,我想首先显示来自验证(步骤 1)的错误消息。
然后来自验证的消息出现了,但是由于我在第 3 步中的 singleShot,另一个出现在它上面。我想在第一个关闭时最早显示第二个。 (重要的是,第一条消息最早会在相关子小部件显示时出现。)
示例代码:
class MySubwidget : public QWidget
{
// omitted (ctor, etc.)
protected:
void showEvent( QShowEvent* e )
{
QShowEvent( e );
QTimer::singleShot( 200, this, SLOT(onShowEventFinished()) );
};
private slots:
void onShowEventFinished()
{
bool showEntryHint = false;
// omitted (some stuff to determine to show an entry hint or not)
if( showEntryHint )
{
QMessageBox t_MessageBox( this );
// omitted (set up the message box
t_MessageBox.exec();
}
};
};
我尝试了不同的方法来解决这个问题,在 QMessageBox
派生的 class 中使用 QMutex
、QWaitCondition
或 QSemaphore
,但这没有无法正常工作,因为消息框的执行在同一个线程中。
这意味着,当第一个消息框以 QMessageBox::exec()
开始时,QApplication::processEvents
(由 QMessageBox
调用)导致调用我的插槽并调用 QMessageBox::exec()
两次(对于第二个提示,第一个 exec()
一直存在,直到第一个消息框关闭)。
我目前的解决方法是在显示 MyMessageBox
的另一个实例时调用 QApplication::processEvents()
的子 class:
class MyMessageBox : public QMessageBox
{
public:
// omitted (ctor, etc.)
int exec()
{
while( MessageBoxShowingCount > 0 )
QApplication::processEvents();
return QMessageBox::exec();
};
protected:
void showEvent( QShowEvent* e )
{
MessageBoxShowingCount++;
QMessageBox::showEvent(e);
};
void hideEvent( QHideEvent* e )
{
QMessageBox::hideEvent(e);
MessageBoxShowingCount--;
};
static int MessageBoxShowingCount = 0;
};
(对于此解决方案,我已将所有 QMessageBox
-实例替换为 MyMessageBox
-实例。)
您似乎需要的是一个应用程序范围的消息管理器。 QMessageBox
然后成为 class 的实现细节,不再直接使用。当您想显示消息时,您可以使用 MessageManager
class.