如何在PyQt或PySide中更改最小化事件的行为?

6

我正在开发一个Qt应用程序,并使用closeEvent虚函数改变了关闭行为,如下:

class MainWindow(QMainWindow):
    def closeEvent(self, event):
            event.ignore()
            self.hide()
            self.trayicon.showMessage('Running', 'Running in the background.')

这个代码按预期工作。如果我删除 event.ignore(),应用程序将按预期退出,一切正常。

我也想控制最小化事件,所以当用户单击标题栏上的最小化按钮时,我想移动窗口而不是最小化。

我不能使用 hideEvent 虚函数,因为事件仍然会被发送到窗口,所以此代码:

def hideEvent(self, event):
    event.ignore()
    self.move(0,0)

将窗口移动到左上角,然后最小化它。在这里,event.ignore()没有效果,因此我尝试使用QtCore.QObject.event这种方式:

def event(self, event):
    if event.type() == QEvent.WindowStateChange:
        if self.isMinimized():
            event.ignore()
            self.move(0,0)
            return True
    return False

窗口移动后又最小化了。这是怎么回事?我怎样才能完全覆盖最小化事件?
1个回答

6

尝试使用changeEvent并筛选WindowMinimized事件,像这样:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from PyQt4 import QtGui, QtCore

class MyWindow(QtGui.QWidget):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)

        self.systemTrayIcon = QtGui.QSystemTrayIcon(self)
        self.systemTrayIcon.setIcon(QtGui.QIcon.fromTheme("face-smile"))
        self.systemTrayIcon.setVisible(True)
        self.systemTrayIcon.activated.connect(self.on_systemTrayIcon_activated)

        self.label = QtGui.QLabel(self)
        self.label.setText("Minimize me!")

        self.layoutVertical = QtGui.QVBoxLayout(self)
        self.layoutVertical.addWidget(self.label)

    @QtCore.pyqtSlot(QtGui.QSystemTrayIcon.ActivationReason)
    def on_systemTrayIcon_activated(self, reason):
        if reason == QtGui.QSystemTrayIcon.DoubleClick:
            if self.isHidden():
                self.show()

            else:
                self.hide()

    def changeEvent(self, event):
        if event.type() == QtCore.QEvent.WindowStateChange:
            if self.windowState() & QtCore.Qt.WindowMinimized:
                event.ignore()
                self.close()
                return

        super(MyWindow, self).changeEvent(event)

    def closeEvent(self, event):
        event.ignore()
        self.hide()
        self.systemTrayIcon.showMessage('Running', 'Running in the background.')

if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('MyWindow')

    main = MyWindow()
    main.show()

    sys.exit(app.exec_())

如果我运行这个程序,窗口标题会停留在任务栏上。当我点击它时,MyWindow将变成灰色和空白。很奇怪。如果我将self.hide()更改为self.move(),移动后仍然会发生最小化。 :( - kissgyorgy
@Walkman 请查看我的更新答案,我已经更新了它以修改最小化事件的行为。 - user1006989
相同的效果,奇怪的行为。标题栏停留在Windows任务栏上,当我尝试使用self.move(0,0)移动时,它会移动并再次最小化。我更新了我的问题,也许现在更清楚我想要什么。 - kissgyorgy
@Walkman 上面的代码在这里运行良好,看起来像是一些与操作系统相关的问题,请尝试使用 QTimer,即 QtCore.QTimer.singleShot(0, self.close) 而不是 self.close() - user1006989
单拍也不起作用,所以可能是Windows 8的问题!无论如何,还是谢谢你的尝试! - kissgyorgy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接