PyQt:在系统托盘应用程序中显示菜单

新手上路,请多包涵

首先,我是一位经验丰富的 C 程序员,但对 Python 还是个新手。我想使用 pyqt 在 python 中创建一个简单的应用程序。让我们想象一下这个应用程序,它很简单,当它运行时,它必须在系统托盘中放置一个图标,并且它在其菜单中提供了一个选项来退出应用程序。

这段代码有效,它显示了菜单(为了简单起见,我没有连接退出操作等)

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

但这不是:

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

我可能错过了什么。没有错误,但在第二种情况下,当我单击右键时,它不显示菜单。

原文由 Nextorlg 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 775
2 个回答

好吧,经过一些调试我发现了问题。 QMenu 对象在完成 __init__ 函数后被销毁,因为它没有父对象。虽然 QSystemTrayIcon 的父对象可以是 QMenu 的对象,但它必须是 Qwidget。此代码有效(请参阅 QMenu 如何获得与作为 QWidget 的 QSystemTrayIcon 相同的父级):

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

原文由 Nextorlg 发布,翻译遵循 CC BY-SA 2.5 许可协议

这是 PyQt5 版本(能够实现 demosthenes 答案的 Exit 动作)。从 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)
        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=r''# ADD PATH OF YOUR ICON HERE .png works
    main(on)

原文由 MagTun 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题