首先,我是一名经验丰富的 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()
我可能错过了什么。没有错误,但在第二种情况下,当我单击右键时,它不显示菜单。
嗯,经过一番调试,我发现了问题。 QMenu 对象在完成
__init__
函数后被销毁,因为它没有父对象。虽然 QSystemTrayIcon 的父对象可以是 QMenu 的对象,但它必须是 Qwidget。这段代码有效(看看 QMenu 如何获得与 QSystemTrayIcon 相同的父级,QSystemTrayIcon 是一个 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()
我想我更喜欢以下内容,因为它似乎不依赖于 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()
这是实现退出操作的代码
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()
这里是 PyQt5 版本(能够实现 demosthenes 答案的退出操作)。 从 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)
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)
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()
import sys
try:
from PySide6 import QtWidgets
from PySide6.QtWidgets import QApplication
from PySide6.QtGui import (QIcon)
from PySide6.QtCore import (QSize)
except ImportError as e:
print("no pyside6")
print("use python.exe -m pip install pyside6")
print(str(e))
exit(0)
from silnik.mytray import SystemTrayIcon
if __name__ == "__main__":
app = QApplication(sys.argv)
ico = QIcon()
ico.addFile(u":/img/brylant_64x64.png", QSize(64, 64))
ico.addFile(u":/img/brylant_16x16.png", QSize(16, 16))
ico.addFile(u":/img/brylant_32x32.png", QSize(32, 32))
ico.addFile(u":/img/brylant_48x48.png", QSize(48, 48))
ico.addFile(u":/img/brylant_128x128.png", QSize(128, 128))
app.setWindowIcon(ico)
trayIcon = silnik.mytray.SystemTrayIcon(ico)
app.tray = trayIcon
trayIcon.show()
在 silnik 文件夹中
创建 mytray.py:
import sys
from PySide6.QtWidgets import (QSystemTrayIcon, QMenu)
from PySide6.QtCore import (QCoreApplication)
class SystemTrayIcon(QSystemTrayIcon):
def __init__(self, icon):
super().__init__()
self.setIcon(icon)
self.menu = QMenu()
self.exitAction = self.menu.addAction("Wyjście")
self.setContextMenu(self.menu)
self.exitAction.triggered.connect(self.exit)
def exit(self):
QCoreApplication.exit()
相反:
QtWidgets.QSystemTrayIcon.__init__(self, icon, parent)
写:
super().__init__(self, icon, parent)
self 这非常重要。那么你的代码就是为了那个self而工作的。如果你不写 self,也许你的程序开始崩溃。
我的代码:
从 PyQt6.QtWidgets 导入 * 从 PyQt6.QtGui 导入 * 来自 PyQt6.QtCore 导入 *tray tab_context_menu= QMenu() #为系统创建菜单tray_context_menu.addAction("First Action") 托盘_context_menu.addSeparator()托盘_context_menu.addAction(“第二个 行动”)
self.my_tray = QSystemTrayIcon(self) #创建系统托盘self.my_tray.setIcon(QIcon("my_icon.png")) self.my_tray.setToolTip("工具提示") self.my_tray.setContextMenu(tray_context_menu) self.my_tray.setVisible(True) # 显示 self.my_tray.show() # 显示
self.my_tray.showMessage("我的标题", "欢迎来到我的程序") #也可以显示消息#这条消息的图标是“信息” 图标”,显示时间为10秒。您还可以设置图标和时间。
self.my_tray.activated.connect(self.onTrayIconActivated)#也可以获取是否激活
def onTrayIconActivated(自我,原因): 如果原因== QtGui.QSystemTrayIcon.Trigger: print(">>> 单击了系统托盘图标")
if reason == QtGui.QSystemTrayIcon.DoubleClick: print(">>> system tray icon double clicked")