PyQt4 Minimize to Tray

不打扰是莪最后的温柔 提交于 2019-11-26 19:20:00

问题


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.

Has anybody done this? Any direction would be appreciated.

Using Python 2.5.4 and PyQt4 on Window XP Pro


回答1:


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.



回答2:


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

Notes:

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

"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.

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()



回答3:


Just to add to the example by Chris:

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

correct:

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

and not the PyQt one

incorrect and 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.




回答4:


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

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



回答5:


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).

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()



回答6:


This is the correct way to handle double click on a tray icon for 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



回答7:


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()


来源:https://stackoverflow.com/questions/758256/pyqt4-minimize-to-tray

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!