2009-04-16 14 views
22

C'è un modo per ridurre a icona il vassoio in PyQt4? Ho già lavorato con la classe QSystemTrayIcon, ma ora vorrei ridurre a icona o "nascondere" la finestra della mia app e mostrare solo l'icona della barra delle applicazioni.PyQt4 Riduci al minimo nel cassetto

Qualcuno ha fatto questo? Qualsiasi indicazione sarà apprezzata.

Usare Python 2.5.4 e PyQt4 su Window XP Pro

risposta

29

E 'piuttosto semplice, una volta si ricorda che non c'è modo di ridurre al minimo sino al system tray.

Al contrario, è fingere in questo modo:

  1. Cattura l'evento minimizzare sulla vostra finestra
  2. Nel gestore di eventi minimizzare, creare e visualizzare una QSystemTrayIcon
  3. Anche nel gestore di eventi minimizzare, chiama hide() o setVisible (false) sulla tua finestra
  4. Catch un clic/doppio clic/menu sulla barra delle applicazioni icona
  5. Nel gestore di eventi dell'icona nella barra delle applicazioni, call show() o setVisible (true) sulla tua finestra, e opzionalmente nascondere l'icona del vassoio.
12

Codice aiuta, quindi ecco qualcosa che ho scritto per un'applicazione, fatta eccezione per closeEvent invece di minimizzare l'evento.

Note:

"CloseEvent (evento)" è un evento override Qt, quindi deve essere messo nella classe che implementa la finestra che si desidera nascondere.

"okayToClose()" è una funzione che si potrebbe considerare l'implementazione (o un flag booleano che si desidera memorizzare) poiché a volte si desidera effettivamente uscire dall'applicazione anziché ridurla a systray.

C'è anche un esempio di come mostrare() di nuovo la finestra.

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

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

+0

ho aggiunto @ suggerimento di mojo di flessibilità nel modo in cui l'icona della barra di sistema viene gestito. Il codice originale proveniva da un'applicazione in cui l'icona del vassoio era sempre visibile, il self.trayIcon.hide() era in modo tale che l'icona non rimaneva nella barra delle applicazioni dopo l'uscita (comportamento tipico delle finestre, purtroppo). Si noti che ora l'utente deve implementare il metodo showEvent (evento) e chiamare self.trayIcon.hide() per completare questo esempio. Dovrei aver appena postato un esempio di minimizzazione/solo ripristino in primo luogo :) –

7

solo per aggiungere l'esempio da Chris:

E 'fondamentale che si utilizza la notazione Qt quando dichiara il segnale, vale a dire

corretto:

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

e non il PyQt one

errato e non funzionerà:

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

Nota la :: nella stringa di segnale. Mi ci sono voluti circa tre ore per capire.

+0

Per favore abbellisci quanto sopra con >> "CRUCIAL che usi Qt NOTATION" <<. Sono stato qui da molto tempo .. pensa ore di riflessione .. facendo altre cose finché non leggo questo post .. == QtCore.SISNAL ("attivato (QSystemTrayIcon :: ActivationReason)") .. cioè senza motivo ;-) – PedroMorgan

+0

def create_sys_tray (self): \t \t self.sysTray = QtGui.QSystemTrayIcon (auto) \t \t self.sysTray.setIcon (QtGui.QIcon ('../ images/corp/blip_32.png')) \t \t self.sysTray.setVisible (true) \t \t self.connect (self.sysTray, QtCore.SIGNAL ("attivato (QSystemTrayIcon :: ActivationReason)"), self.on_sys_tray_activated) \t \t \t \t self.sysTrayMenu = QtGui.QMenu (auto) \t \t atto = self.sysTrayMenu.addAction ("foo") \t \t \t def on_sys_tray_activated (self, ragione): \t \t stampa "ragionevole =", la ragione – PedroMorgan

4

code..Thanks Qui sta lavorano Matze per cruciale, il segnale mi hanno portato più ore di curiosità .. ma a fare altre cose. quindi per 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

Questo è il codice e lo fa aiuto credo nel mondo dello spettacolo mi codice

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

Questo codice sembra orribile. Come è riuscito ad alzarsi i voti è oltre la comprensione. – qed

3

Questa è stata una modifica della risposta vzades, ma è stato respinto da una serie di motivi . Fa esattamente la stessa cosa del loro codice, ma obbedirà anche al minimizzare l'evento (ed eseguirà senza errori di sintassi/icone mancanti).

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

Come faccio a mostrare solo l'icona del vassoio dopo l'avvio? Se sposto la linea setWindowFlags su initUI(), non ha alcun effetto, la finestra normale appare ancora – Shuman

0

Questo è il modo corretto per gestire il doppio clic sull'icona di un vassoio per 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

Capisco che questo non risponda direttamente alla domanda, ma questa domanda ha molte viste e le persone di Google stanno cercando un altro risposta aggiornata. – Veehmot

Problemi correlati