【问题标题】:How to hide/minmize window when clicking x button单击x按钮时如何隐藏/最小化窗口
【发布时间】:2021-05-24 05:52:40
【问题描述】:

背景: 当单击“x”按钮而不是关闭整个应用程序时,隐藏自身(或将其最小化,或仅关闭“主窗口”)的应用程序很常见。在mac中,关闭窗口是“command+w”,而关闭应用程序是“command+q”。它们是不同的。

问题:closeEvent 不够用。在 PyQT5 中,wo 可以在任何 QWindow/QDialog/QWidget 中挂钩 closeEvent 并拒绝该事件。我们可以通过self.hide()隐藏窗口。

def closeEvent(self, event):
  event.reject()
  self.hide()

但是,如果我们这样做,窗口将变得无法停止,因为其他关闭方式(Command+Q 或右键单击图标然后退出或通过菜单栏退出)都被阻止了。 (这很有趣,因为无论如何都无法关闭该应用程序。)

可能的解决方案:

  1. 隐藏 x 按钮。这是一种权宜之计,但解决了这个问题,因为我想要的是通过 x 按钮隐藏窗口,而不是删除按钮。
  2. 找到一个不同于 closeEvent 的事件,它可以将 X 按钮与其他按钮区分开来并阻止该事件。但很遗憾,我看不到这样的事件。如果事件存在,也许我会有另一个问题[1]
  3. 继续阻塞closeEvent,并hook其他绑定“command+Q”或“右键退出”的事件。然后在那个偶数钩子中强制退出应用程序。在这种情况下,我的问题变成:我可以通过一些 Qt 对象连接退出或 (command+Q)
  4. 也许还有其他更好的解决方案。

这篇文章可能与How to write event for window close(X) button in pyqt4 python类似,但与“如何使用Qt禁用窗口关闭按钮”的所谓“重复”完全不同

[1]。这不是一个大问题,但相关。一旦窗口被隐藏,我们需要一个“单击任务栏/停靠栏中的图标”事件来显示它。是否有一些对象绑定到事件?

【问题讨论】:

  • 我不确定我是否关注你。您希望在使用 cmd+q 时仍然能够关闭窗口/退出程序,但在使用 cmd+w 或关闭按钮时将其隐藏?
  • @musicamante 没错!
  • 嗯,我似乎记得我遇到过类似的问题,因为我记得重复 closeEvents 的奇怪行为。不幸的是,我现在无法运行 macOS,但您可以尝试检查 if 设置连接到aboutToQuit 信号的内部标志实际上已完成之前最终的closeEvent 是调用:如果是这种情况,您可以检查它是否是自发的是否已经设置了该标志。
  • @musicamante 谢谢!目前它对我不起作用,因为在我的情况下“自发”总是正确的。我将在 Windows 中尝试它。如果我将所有内容都放在 QWidget 而不是 QMainWindow 中,也许它也可以工作。

标签: python macos pyqt event-handling pyqt5


【解决方案1】:

尝试将 WA_QuitOnClose 设置为 False。以下对我有用:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = QMainWindow()
    window.setCentralWidget(QWidget())
    window.setAttribute(Qt.WA_QuitOnClose, False)
    QShortcut(QKeySequence.Close, window, window.close)
    window.show()
    sys.exit(app.exec_())

【讨论】:

  • 嗨@alec 谢谢。如果我只想关闭窗口(cmd+w)而不关闭整个应用程序(cmd+q),这很有用。但我想隐藏窗口而不是真正关闭它。我提到 cmd+w 是因为我想区分 cmd+w 和 cmd+q 以便我可以钩住正确的事件。
【解决方案2】:

检查应用程序是否正在关闭的一种方法(通过右键单击 Dock 中的图标或 cmd+Q)是捕获应用程序的事件。

我认为事件链是: 应用程序关闭 (19) -> 窗口关闭 (19) -> AboutToQuit

因此,如果窗口关闭被阻止,AboutToQuit 将无济于事。我们只需要捕获上游事件,应用程序关闭。

class MyApplication(QApplication):
    def event(self, e):
        if e.type() == 19: # Close event
            sys.exit() # Or we can do other things to "force close"
class MyWindow(QMainWindow):
    def closeEvent(self, e):
        e.ignore()

if __name__ == '__main__':
    app = MyApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())

【讨论】:

    猜你喜欢
    • 2011-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    相关资源
    最近更新 更多