没有双重/同时只有一个 QMessageBox

No double / Only one QMessageBox at same time

在我的申请中,我有以下情况:

  1. QTabWidget 输入的验证方法中,我要确定子小部件输入的错误。
  2. 因此我将此子小部件设置为活动小部件
  3. 在这个小部件的 showEvent 中,我将 QTimer::singleShot 触发到方法 onShowEventFinished() 中,我将在其中显示 QMessageBox
  4. 激活新的子小部件后,我想首先显示来自验证(步骤 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 中使用 QMutexQWaitConditionQSemaphore,但这没有无法正常工作,因为消息框的执行在同一个线程中。

这意味着,当第一个消息框以 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.