2009-04-16 24 views
22

¿Hay alguna forma de minimizar 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.PyQt4 Minimize to Tray

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

utilizar Python 2.5.4 y PyQt4 en Windows XP Pro

Respuesta

29

Es bastante sencillo una vez que recuerde que no hay manera de minimizar realidad a la system tray.

En su lugar, es falso al hacer esto:

  1. capturar el evento de Minimizar en la ventana de su
  2. En el controlador de eventos minimizar, crear y mostrar un QSystemTrayIcon
  3. También en el controlador de eventos minimizar, call hide() o setVisible (falso) en su ventana
  4. Captura un elemento de clic/doble clic/menú en el icono de la bandeja del sistema
  5. En el gestor de eventos del icono de la bandeja del sistema, llame a show() o setVisible (true) en su ventana, y opcionalmente oculte su icono de bandeja.
12

El código es útil, así que esto es algo que escribí para una aplicación, excepto para el evento closeEvent en lugar del evento minimize.

Notas:

"CloseEvent (evento)" es un evento reemplazado Qt, por lo que debe ser puesto en la clase que implementa la ventana que desea ocultar.

"okayToClose()" es una función que podría considerar implementar (o un indicador booleano que desee almacenar) ya que a veces realmente desea salir de la aplicación en lugar de minimizarla a la bandeja del sistema.

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

# "minimizar" self.hide() self.trayIcon.show() event.ignore() –

+0

añadí @ sugerencia de mojo de flexibilidad en cómo se maneja el icono de la bandeja del sistema. El código original provenía de una aplicación donde el ícono de la bandeja siempre estaba visible, el archivo self.trayIcon.hide() era para que el ícono no se quedara en la bandeja del sistema después de la salida (el comportamiento típico de Windows, lamentablemente). Tenga en cuenta que ahora el usuario debe implementar el método showEvent (evento) y llamar a self.trayIcon.hide() para completar este ejemplo. Debería haber publicado un ejemplo de minimizar/restaurar solo en primer lugar :) –

7

sólo para añadir al ejemplo de Chris:

Es crucial que utilice la notación Qt cuando se declara la señal, es decir,

correcta:

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

y no el PyQt uno

incorrecta y no funcionará:

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

Nota del :: en la cadena de señal. Esto me llevó aproximadamente tres horas averiguarlo.

+0

Por favor embelle lo anterior con >> "CRUCIAL que su uso Qt NOTATION" <<. He estado aquí por mucho tiempo ... creo que es hora de pensar ... haciendo otras cosas hasta que leo esta publicación ... == QtCore.SISNAL ("activado (QSystemTrayIcon :: ActivationReason)") ... es decir, sin motivo ;-) – PedroMorgan

+0

def create_sys_tray (auto): \t \t self.sysTray = QtGui.QSystemTrayIcon (auto) \t \t self.sysTray.setIcon (QtGui.QIcon ('../ images/corp/blip_32.png')) \t \t self.sysTray.setVisible (Verdadero) \t \t self.connect (self.sysTray, QtCore.SIGNAL ("activa (QSystemTrayIcon :: ActivationReason)"), self.on_sys_tray_activated) \t \t \t \t self.sysTrayMenu = QtGui.QMenu (auto) \t \t act = self.sysTrayMenu.addAction ("foo") \t \t \t def on_sys_tray_activated (sí, la razón): \t \t de impresión "razonable =", razón – PedroMorgan

4

code..Thanks Aquí está trabajando Matze para Crucial, la señal me llevaron más horas de curiosidad .. pero haciendo otras cosas. entonces ta por 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 
1

Este es el código y lo hace ayuda creo en me muestra 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() 
+2

Este código se ve horrible. Cómo logró obtener votos está más allá de la comprensión. – qed

3

Ésta era una edición de la respuesta vzades, pero fue rechazado en una serie de motivos . Hace exactamente lo mismo que su código, pero también obedecerá al evento de minimizar (y se ejecutará sin errores de sintaxis o iconos faltantes).

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

¿Cómo hago que muestre solo el icono de la bandeja después de iniciar? Si muevo la línea setWindowFlags a initUI(), no tiene ningún efecto, la ventana normal sigue apareciendo – Shuman

0

Esta es la forma correcta de hacer 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 
+0

Entiendo que esto no responde la pregunta directamente, pero esta pregunta tiene muchas opiniones y la gente de Google está buscando una más respuesta actualizada. – Veehmot