python PyQt4 最小化到托盘

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/758256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 20:48:40  来源:igfitidea点击:

PyQt4 Minimize to Tray

pythonpyqt4system-trayminimize

提问by Gavin Vickery

Is there a way to minimize to tray in PyQt4? I've already worked with the QSystemTrayIcon class, but now I would like to minimize or "hide" my app window, and show only the tray icon.

有没有办法在 PyQt4 中最小化到托盘?我已经使用了 QSystemTrayIcon 类,但现在我想最小化或“隐藏”我的应用程序窗口,并且只显示托盘图标。

Has anybody done this? Any direction would be appreciated.

有没有人做过这个?任何方向将不胜感激。

Using Python 2.5.4 and PyQt4 on Window XP Pro

在 Window XP Pro 上使用 Python 2.5.4 和 PyQt4

回答by Kevin

It's pretty straightforward once you remember that there's no way to actually minimize to the system tray.

一旦您记住实际上无法最小化到系统托盘,这将非常简单。

Instead, you fake it by doing this:

相反,你通过这样做来伪造它:

  1. Catch the minimize event on your window
  2. In the minimize event handler, create and show a QSystemTrayIcon
  3. Also in the minimize event handler, call hide() or setVisible(false) on your window
  4. Catch a click/double-click/menu item on your system tray icon
  5. In your system tray icon event handler, call show() or setVisible(true) on your window, and optionally hide your tray icon.
  1. 捕捉窗口上的最小化事件
  2. 在最小化事件处理程序中,创建并显示一个 QSystemTrayIcon
  3. 同样在最小化事件处理程序中,在窗口上调用 hide() 或 setVisible(false)
  4. 在系统托盘图标上捕捉单击/双击/菜单项
  5. 在您的系统托盘图标事件处理程序中,在您的窗口上调用 show() 或 setVisible(true),并可选择隐藏您的托盘图标。

回答by Gavin Vickery

Code helps, so here's something I wrote for an application, except for the closeEvent instead of the minimize event.

代码有帮助,所以这是我为应用程序编写的内容,除了 closeEvent 而不是最小化事件。

Notes:

笔记:

"closeEvent(event)" is an overridden Qt event, so it must be put in the class that implements the window you want to hide.

“closeEvent(event)”是一个重写的Qt事件,所以它必须放在实现你想要隐藏的窗口的类中。

"okayToClose()" is a function you might consider implementing (or a boolean flag you might want to store) since sometimes you actually want to exit the application instead of minimizing to systray.

“okayToClose()”是您可能考虑实现的函数(或您可能想要存储的布尔标志),因为有时您实际上想要退出应用程序而不是最小化到系统托盘。

There is also an example of how to show() your window again.

还有一个如何再次显示()窗口的示例。

def __init__(self):
  traySignal = "activated(QSystemTrayIcon::ActivationReason)"
  QtCore.QObject.connect(self.trayIcon, QtCore.SIGNAL(traySignal), self.__icon_activated)

def closeEvent(self, event):
  if self.okayToClose(): 
    #user asked for exit
    self.trayIcon.hide()
    event.accept()
  else:
    #"minimize"
    self.hide()
    self.trayIcon.show() #thanks @mojo
    event.ignore()

def __icon_activated(self, reason):
  if reason == QtGui.QSystemTrayIcon.DoubleClick:
    self.show()

回答by WrongAboutMostThings

Just to add to the example by Chris:

只是添加到 Chris 的示例中:

It is crucialthat you use the Qt notation when declaring the signal, i.e.

在声明信号时使用 Qt 表示法至关重要,即

correct:

正确

self.connect(self.icon, SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.iconClicked)

and not the PyQt one

而不是 PyQt

incorrectand won't work:

不正确且不起作用:

self.connect(self.icon, SIGNAL("activated(QSystemTrayIcon.ActivationReason)"), self.iconClicked)

Note the ::in the signal string. This took me about three hours to figure out.

请注意::信号字符串中的 。这花了我大约三个小时才弄清楚。

回答by PedroMorgan

Here's working code..Thanks Matzefor Crucial, the SIGNAL took me more hours of curiosity.. but doing other things. so ta for a #! moment :-)

这是工作代码..感谢Matze提供Crucial,SIGNAL 花了我更多时间的好奇心.. 但做其他事情。所以要一个#!片刻 :-)

def create_sys_tray(self):
    self.sysTray = QtGui.QSystemTrayIcon(self)
    self.sysTray.setIcon( QtGui.QIcon('../images/corp/blip_32.png') )
    self.sysTray.setVisible(True)
    self.connect(self.sysTray, QtCore.SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), self.on_sys_tray_activated)

    self.sysTrayMenu = QtGui.QMenu(self)
    act = self.sysTrayMenu.addAction("FOO")

def on_sys_tray_activated(self, reason):
    print "reason-=" , reason

回答by Jordan

This was an edit of vzades response, but it was rejected on a number of grounds. It does the exact same thing as their code but will also obey the minimize event (and run without syntax errors/missing icons).

这是对 vzades 回复的编辑,但由于多种原因被拒绝。它与他们的代码完全相同,但也会遵守最小化事件(并且在没有语法错误/缺少图标的情况下运行)。

import sys
from PyQt4 import QtGui, QtCore


class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        style = self.style()

        # Set the window and tray icon to something
        icon = style.standardIcon(QtGui.QStyle.SP_MediaSeekForward)
        self.tray_icon = QtGui.QSystemTrayIcon()
        self.tray_icon.setIcon(QtGui.QIcon(icon))
        self.setWindowIcon(QtGui.QIcon(icon))

        # Restore the window when the tray icon is double clicked.
        self.tray_icon.activated.connect(self.restore_window)

    def event(self, event):
        if (event.type() == QtCore.QEvent.WindowStateChange and 
                self.isMinimized()):
            # The window is already minimized at this point.  AFAIK,
            # there is no hook stop a minimize event. Instead,
            # removing the Qt.Tool flag should remove the window
            # from the taskbar.
            self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.Tool)
            self.tray_icon.show()
            return True
        else:
            return super(Example, self).event(event)

    def closeEvent(self, event):
        reply = QtGui.QMessageBox.question(
            self,
            'Message',"Are you sure to quit?",
            QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
            QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:
            event.accept()
        else:
            self.tray_icon.show()
            self.hide()
            event.ignore()

    def restore_window(self, reason):
        if reason == QtGui.QSystemTrayIcon.DoubleClick:
            self.tray_icon.hide()
            # self.showNormal will restore the window even if it was
            # minimized.
            self.showNormal()

def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

回答by Jorjon

This is the correct way to handle double click on a tray icon for PyQt5.

这是处理 PyQt5 托盘图标双击的正确方法。

def _create_tray(self):
    self.tray_icon = QSystemTrayIcon(self)
    self.tray_icon.activated.connect(self.__icon_activated)

def __icon_activated(self, reason):
    if reason in (QSystemTrayIcon.Trigger, QSystemTrayIcon.DoubleClick):
        pass

回答by vzades

This is the code and it does help i believe in show me the code

这是代码,它确实有助于我相信向我展示代码

import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtGui import QDialog, QApplication, QPushButton, QLineEdit, QFormLayout, QSystemTrayIcon


class Example(QtGui.QWidget):

    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        self.icon = QSystemTrayIcon()
        r = self.icon.isSystemTrayAvailable()
        print r
        self.icon.setIcon(QtGui.QIcon('/home/vzades/Desktop/web.png'))
        self.icon.show()
        # self.icon.setVisible(True)
        self.setGeometry(300, 300, 250, 150)
        self.setWindowIcon(QtGui.QIcon('/home/vzades/Desktop/web.png'))
        self.setWindowTitle('Message box')
        self.show()
        self.icon.activated.connect(self.activate)
        self.show()

    def closeEvent(self, event):

        reply = QtGui.QMessageBox.question(self, 'Message', "Are you sure to quit?", QtGui.QMessageBox.Yes |
                                           QtGui.QMessageBox.No, QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:
            event.accept()
        else:
            self.icon.show()

            self.hide()

            event.ignore()

    def activate(self, reason):
        print reason
        if reason == 2:
            self.show()

    def __icon_activated(self, reason):
        if reason == QtGui.QSystemTrayIcon.DoubleClick:
            self.show()


def main():

    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()