2009-05-21 6 views
22

Tout d'abord, je suis un programmeur C expérimenté mais nouveau pour python. Je veux créer une application simple en python en utilisant pyqt. Imaginons que cette application soit aussi simple que quand elle est lancée, elle doit placer une icône dans la barre d'état système et offrir une option dans son menu pour quitter l'application.PyQt: Afficher le menu dans une application de barre d'état système

Ce code fonctionne, il montre le menu (je ne connecte pas l'action de sortie et ainsi de suite pour rester simple)

import sys 
from PyQt4 import QtGui 

def main(): 
    app = QtGui.QApplication(sys.argv) 

    trayIcon = QtGui.QSystemTrayIcon(QtGui.QIcon("Bomb.xpm"), app) 
    menu = QtGui.QMenu() 
    exitAction = menu.addAction("Exit") 
    trayIcon.setContextMenu(menu) 

    trayIcon.show() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 

Mais cela ne veut pas:

import sys 
from PyQt4 import QtGui 

class SystemTrayIcon(QtGui.QSystemTrayIcon): 

    def __init__(self, icon, parent=None): 
     QtGui.QSystemTrayIcon.__init__(self, icon, parent) 
     menu = QtGui.QMenu() 
     exitAction = menu.addAction("Exit") 
     self.setContextMenu(menu) 

def main(): 
    app = QtGui.QApplication(sys.argv) 

    trayIcon = SystemTrayIcon(QtGui.QIcon("Bomb.xpm"), app) 

    trayIcon.show() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 

I probablement manquer quelque chose. Il n'y a pas d'erreur mais dans le second cas, lorsque je clique avec le bouton droit, le menu n'apparaît pas.

+2

En tant que compagnon de programmeur C juste dans Python. Je peux dire "errrmmm" aussi. –

+0

Si votre réponse résout le problème, s'il vous plaît choisir la copie de votre réponse de communauté-wiki comme "la" réponse (je n'obtiendrai aucune réputation :). J'ai également édité votre réponse pour corriger une faute de frappe mineure. – tzot

Répondre

26

Eh bien, après un débogage, j'ai trouvé le problème. L'objet QMenu est détruit après avoir terminé la fonction __init__ car il n'a pas de parent. Alors que le parent d'un QSystemTrayIcon peut être un objet pour le QMenu, il doit s'agir d'un Qwidget. Ce code fonctionne (voir comment QMenu obtient le même parent que l'QSystemTrayIcon qui est un QWidget):

import sys 
from PyQt4 import QtGui 

class SystemTrayIcon(QtGui.QSystemTrayIcon): 

    def __init__(self, icon, parent=None): 
     QtGui.QSystemTrayIcon.__init__(self, icon, parent) 
     menu = QtGui.QMenu(parent) 
     exitAction = menu.addAction("Exit") 
     self.setContextMenu(menu) 

def main(): 
    app = QtGui.QApplication(sys.argv) 

    w = QtGui.QWidget() 
    trayIcon = SystemTrayIcon(QtGui.QIcon("Bomb.xpm"), w) 

    trayIcon.show() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 
7

Je pense que je préférerais la suivante car il ne semble pas dépendre de décisions de collecte des ordures internes de QT.

import sys 
from PyQt4 import QtGui 

class SystemTrayIcon(QtGui.QSystemTrayIcon): 
    def __init__(self, icon, parent=None): 
     QtGui.QSystemTrayIcon.__init__(self, icon, parent) 
     self.menu = QtGui.QMenu(parent) 
     exitAction = self.menu.addAction("Exit") 
     self.setContextMenu(self.menu) 

def main(): 
    app = QtGui.QApplication(sys.argv) 
    style = app.style() 
    icon = QtGui.QIcon(style.standardPixmap(QtGui.QStyle.SP_FileIcon)) 
    trayIcon = SystemTrayIcon(icon) 

    trayIcon.show() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 
+0

Pourquoi apparaît-il dans la barre d'ancrage de Mac OSx? –

+0

Wow, donc ce n'est pas du tout le systray? – fatuhoku

3

Voici le code avec l'action de sortie mis en œuvre

import sys 
from PyQt4 import QtGui, QtCore 

class SystemTrayIcon(QtGui.QSystemTrayIcon): 
    def __init__(self, icon, parent=None): 
     QtGui.QSystemTrayIcon.__init__(self, icon, parent) 
     menu = QtGui.QMenu(parent) 
     exitAction = menu.addAction("Exit") 
     self.setContextMenu(menu) 
     QtCore.QObject.connect(exitAction,QtCore.SIGNAL('triggered()'), self.exit) 

    def exit(self): 
     QtCore.QCoreApplication.exit() 

def main(): 
    app = QtGui.QApplication(sys.argv) 

    w = QtGui.QWidget() 
    trayIcon = SystemTrayIcon(QtGui.QIcon("qtLogo.png"), w) 

    trayIcon.show() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 
+0

Note *: Vous devez avoir une image qtLogo.png dans le même répertoire que le script – demosthenes

0

Voici la version PyQt5 (a été en mesure de mettre en œuvre l'action de la sortie de la réponse de Démosthène). Source pour le portage de PyQt4 à PyQt5

import sys 
from PyQt5 import QtCore, QtGui, QtWidgets 
# code source: https://stackoverflow.com/questions/893984/pyqt-show-menu-in-a-system-tray-application - add answer PyQt5 
#PyQt4 to PyQt5 version: https://stackoverflow.com/questions/20749819/pyqt5-failing-import-of-qtgui 
class SystemTrayIcon(QtWidgets.QSystemTrayIcon): 

    def __init__(self, icon, parent=None): 
     QtWidgets.QSystemTrayIcon.__init__(self, icon, parent) 
     menu = QtWidgets.QMenu(parent) 
     exitAction = menu.addAction("Exit") 
     self.setContextMenu(menu) 

def main(image): 
    app = QtWidgets.QApplication(sys.argv) 

    w = QtWidgets.QWidget() 
    trayIcon = SystemTrayIcon(QtGui.QIcon(image), w) 

    trayIcon.show() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    on=r''# ADD PATH OF YOUR ICON HERE .png works 
    main(on) 
0

Avec un événement connecté à pyqt5:

class SystemTrayIcon(QtWidgets.QSystemTrayIcon): 

    def __init__(self, icon, parent=None): 
     QtWidgets.QSystemTrayIcon.__init__(self, icon, parent) 
     menu = QtWidgets.QMenu(parent) 
     exitAction = menu.addAction("Exit") 
     self.setContextMenu(menu)  
     menu.triggered.connect(self.exit) 

    def exit(self): 
     QtCore.QCoreApplication.exit() 
Questions connexes