【问题标题】:Window is hidden even though QCloseEvent is ignored即使 QCloseEvent 被忽略,窗口也被隐藏
【发布时间】:2013-01-16 23:03:18
【问题描述】:

我目前正在尝试将我的 Qt 应用程序移植到 Mac OSX,但遇到了以下问题:

我的一个窗口类(从 QMainWindow 派生)在按下关闭按钮时显示一个对话框,您可以在其中保存/放弃更改或中止。这是通过重新实现 closeEvent 来完成的,如下所示:

void ResultsWindow::closeEvent(QCloseEvent* event)
{
    if (isWindowModified())
    {
        activateWindow();
        QMessageBox::StandardButton button = QMessageBox::warning(
                this,
                APPLICATION_NAME,
                "Warning: data have been modified. Do you want to save the "
                    "changes?",
                QMessageBox::Save | QMessageBox::Discard | QMessageBox::Abort,
                QMessageBox::Abort);
        switch (button)
        {
            case QMessageBox::Save:
                if (!Save())
                {
                    event->ignore();
                    return;
                }
                break;
            case QMessageBox::Discard:
                break;
            case QMessageBox::Abort:
            default:
                event->ignore();
                return;
        }
    }
    event->accept();
}

预期的行为如下:如果单击“中止”,则忽略该事件并且窗口保持打开状态。这在 Linux 和 Windows 上按预期工作。然而,在 OSX 上,该窗口是隐藏的,但在后台仍处于活动状态。我在这里想念什么?如何确保窗口保持打开状态?

更新: 我不知何故认为这是 Qt5 的问题。如果closeEvent 方法只包含event->ignore();,则窗口仍然关闭。我不认为这是预期的行为。也许我应该将此问题发布到 Qt 邮件列表...

更新: 这是 Qt 中的一个错误,自 5.1 版起已解决。

【问题讨论】:

  • 如果你有时间,试试这个看看我能不能回答这个问题:调用`event->accept();`作为第一个函数(禁用完全关闭应用程序),看看窗口是否尽管单击关闭按钮,仍将保持可见。
  • 我不确定我是否理解正确:我只是用event->accept();event->ignore(); 替换了函数体。在这两种情况下,窗口都关闭了,但在后一种情况下,它在后台保持活动状态。
  • 出于好奇,做 QTimer::singleShot(0, this, SLOT(show()) 有什么效果吗?
  • 哪个版本的 Qt?我在 Mac OX 10.8.2 上使用 4.8.1,它工作正常。
  • 我在 Snow Leopard 上使用 Qt 5.0.0。同样的影响也发生在最近的一只山狮身上。

标签: c++ macos qt qt5


【解决方案1】:

我在 Mac 10.7 上安装了 Qt 4.7,但无法重现此错误。

我相信每次忽略event 时,只需将show() 放在Q_OS_MAC 宏之间就可以了。像这样的:

event->ignore();
#ifdef Q_OS_MAC
     show();
#endif

这可能不是完美的解决方案,但肯定可以解决这个问题。

【讨论】:

  • 我试过这个,但没有用。窗户仍然关闭。但我预计这一点,因为从外部调用 show(),在窗口被隐藏之后,也没有效果。
【解决方案2】:

这里与 Qt 5.0.0 或 Qt 5.0.1 相同。 但是,如果您将 WindowModality 设置为 ApplicationModal 或 WindowModal,则它可以工作。按 Cmd+Q 退出并获取消息框。

我认为问题是由 Mac OS X UI 和其他 UI 之间的差异引起的。也许在 Qt 上的一些额外工作将使他们能够解决问题。

即使你重新实现 QMainWindow::event() 也会得到相同的结果。

【讨论】:

  • 事实上,如果您有 WindowModality = NonModal 并使用 cmd+Q,当您按下“Abort”时,窗口不会消失。如果您使用红色按钮然后“中止”窗口消失,但您可以按 cmd+Q 再次显示消息框。
  • 嗯,这在某种程度上可行,但不是真的......我将窗口模式设置为Qt::WindowModal,但现在它的关闭按钮被禁用,并且主窗口也不再可访问,好像结果窗口是应用模式。但是,如果我从任务栏关闭应用程序,则会出现对话框并选择“中止”导致窗口保持打开状态......
  • 事实上,红色按钮不应该关闭应用程序,而只是关闭窗口;它不同于任务栏(cmd+Q)。我的意思是,我希望这可能是一种解决方法(特别是如果这是您的应用程序的主窗口),直到 Qt 开发人员解决该错误。
  • 问题是,红色按钮在您的建议中不可用。这不是我的应用程序的主窗口,如果我不想添加其他按钮,现在没有办法关闭它。此外,我不能再访问主窗口,因为窗口模式也不知何故是错误的……现在我宁愿让它保持以前的状态:-/
  • 不是主窗口,它是 QMainWindow 的子类?奇怪的。为什么不是 QDialog?
【解决方案3】:

而不是

case QMessageBox::Abort:
                default:
                        event->ignore();
                        return;

尝试做

case QMessageBox::Abort:
                       event->ignore();
                       return;
 default:
         break

【讨论】:

  • 这并没有改变任何东西,问题不是开关结构格式错误。
【解决方案4】:

当我也遇到这个错误时,我在这里创建了一个错误报告:https://bugreports.qt-project.org/browse/QTBUG-30899

【讨论】:

    【解决方案5】:

    丑陋的解决方法(经过测试和工作),在 event->ignore() 之后添加这个:

    QTimer::singleShot(0,this,SLOT(hide()));
    QTimer::singleShot(100,this,SLOT(show()));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      相关资源
      最近更新 更多