views:

2157

answers:

3

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

+14  A: 

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.
Iceman
+8  A: 

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()
Chris Cameron
#"minimize" self.hide() self.trayIcon.show() event.ignore()
mojo
I added @mojo's suggestion for flexibility in how the system tray icon is handled. The original code came from an application where the tray icon was always visible, the self.trayIcon.hide() was so that the icon didn't stick around on the system tray after exit (typical windows behaviour, sadly). Note that now the user must implement the showEvent(event) method and call self.trayIcon.hide() to complete this example. I should have just posted a minimize/restore-only example in the first place :)
Chris Cameron
+2  A: 

Just to add to the example by Chris:

It is crucial that you use the Qt notation when declaring the signal, ie

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.

Matze