PyQt: Show menu in a system tray application

前端 未结 6 1102
后悔当初
后悔当初 2020-12-02 08:45

First of all, I\'m an experienced C programmer but new to python. I want to create a simple application in python using pyqt. Let\'s imagine this application it is as simple

相关标签:
6条回答
  • 2020-12-02 09:24

    I think I would prefer the following as it doesn't seem to depend upon QT's internal garbage collection decisions.

    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 讨论(0)
  • With a pyqt5 connected event:

    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()
    
    0 讨论(0)
  • 2020-12-02 09:38

    I couldn't get any of the above answers to work in PyQt5 (the exit in the system tray menu, wouldn't actually exit), but i managed to combine them for a solution that does work. I'm still trying to determine if exitAction should be used further somehow.

    import sys
    from PyQt5 import QtWidgets, QtCore, 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)
            menu.triggered.connect(self.exit)
    
        def exit(self):
            QtCore.QCoreApplication.exit()
    
    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='icon.ico'
        main(on)
    
    0 讨论(0)
  • 2020-12-02 09:39

    Here is the PyQt5 version (was able to implement the Exit action of demosthenes's answer). Source for porting from PyQt4 to 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 讨论(0)
  • 2020-12-02 09:46

    Well, after some debugging I found the problem. The QMenu object it is destroyed after finish __init__ function because it doesn't have a parent. While the parent of a QSystemTrayIcon can be an object for the QMenu it has to be a Qwidget. This code works (see how QMenu gets the same parent as the QSystemTrayIcon which is an 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()
    
    0 讨论(0)
  • 2020-12-02 09:46

    Here is the code with Exit action implemented

    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 讨论(0)
提交回复
热议问题