PyQt4 Minimizar a la bandeja

¿Hay una manera de minimizar a la bandeja en PyQt4? Ya he trabajado con la clase QSystemTrayIcon, pero ahora me gustaría minimizar u “ocultar” la ventana de mi aplicación y mostrar solo el icono de la bandeja.

¿Alguien ha hecho esto? Cualquier dirección podría ser apreciada.

Uso de Python 2.5.4 y PyQt4 en Windows XP Pro

Es bastante sencillo una vez que recuerdes que no hay forma de minimizar realmente la bandeja del sistema .

En su lugar, lo finges haciendo esto:

  1. Captura el evento minimizado en tu ventana
  2. En el controlador de eventos Minimizar, cree y muestre un QSystemTrayIcon
  3. También en el controlador de eventos de minimización, llame a hide () o setVisible (false) en su ventana
  4. Capture un clic / doble clic / elemento de menú en el icono de la bandeja del sistema
  5. En el controlador de eventos del icono de la bandeja del sistema, llame a show () o setVisible (verdadero) en su ventana y, opcionalmente, oculte el icono de la bandeja.

El código ayuda, así que aquí hay algo que escribí para una aplicación, excepto el evento closeEvent en lugar del evento minimizador.

Notas:

“closeEvent (evento)” es un evento Qt invalidado, por lo que debe colocarse en la clase que implementa la ventana que desea ocultar.

“okayToClose ()” es una función que podría considerar implementar (o una bandera booleana que tal vez quiera almacenar) ya que a veces realmente desea salir de la aplicación en lugar de minimizarla a systray.

También hay un ejemplo de cómo mostrar () su ventana nuevamente.

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

Solo para agregar al ejemplo de Chris:

Es crucial que use la notación Qt al declarar la señal, es decir,

correcto :

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

y no el de PyQt

incorrecto y no funcionará:

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

Note el :: en la cadena de señal. Esto me tomó cerca de tres horas para averiguar.

Aquí está el código de trabajo … Gracias a Matze por Crucial , la SEÑAL me llevó más horas de curiosidad … pero haciendo otras cosas. así que para un #! momento 🙂

 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 

Esta fue una edición de la respuesta de vzades, pero fue rechazada por varios motivos. Hace exactamente lo mismo que su código pero también obedece el evento de minimización (y se ejecuta sin errores de syntax / íconos que faltan)

 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.restre_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 restre_window(self, reason): if reason == QtGui.QSystemTrayIcon.DoubleClick: self.tray_icon.hide() # self.showNormal will restre 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() 

Este es el código y ayuda, creo en mostrarme el código

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

Esta es la forma correcta de manejar el doble clic en el icono de una bandeja para 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