PyQT5 QSystemTrayIcon激活信号不起作用

时间:2017-04-27 12:30:47

标签: python pyqt pyqt5 qsystemtrayicon

我想在PyQT5程序中单击系统托盘图标时打印文本。我试图将PyQT5 QSystemTrayIcon激活信号(单击系统托盘图标时发出)连接到自定义方法,但不调用该方法。 这是一个简单的例子:

import sys
from PyQt5.QtWidgets import QSystemTrayIcon, QApplication
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot


@pyqtSlot()
def action(signal):
    print('test1')

app = QApplication(sys.argv)
icon = QSystemTrayIcon(QIcon('any_icon.png'), app)
icon.show()

icon.activated.connect(action)
#icon.activated['QSystemTrayIcon::ActivationReason'].connect(action)
#icon.pyqtConfigure(activated=action)

print(icon.receivers(icon.activated))  # to check if is connected
sys.exit(app.exec_())

在示例中有3种方式将信号连接到插槽(其中两个已注释)。我尝试使用带有和不带装饰器的方法@pyqtSlot()。连接没有引起错误。甚至信号接收器的打印也表示它连接到1个插槽。但是,单击systray图标时它不会执行任何操作。

问题:信号连接是否错误,或信号是否完全没有发出?

系统:Ubuntu 16.04,PyQT5.8。但是,由于PyQT是多平台的,因此也应该在其他系统上工作。 PS:我已经阅读了official PyQT5 signal/slot documentation以及关于堆栈溢出的许多相关问题,但没有找到相同的问题。我认为最接近的可能是is in C++,但不适用于python。 任何提示都会非常感激。非常感谢你! 编辑:修复了文本中的拼写错误

2 个答案:

答案 0 :(得分:1)

你的例子在使用stalonetray的openbox下的Xubuntu中运行得很好。 但是在Xubuntu中,它没有用! 但是当我添加类似的东西时:

mNu =  QMenu() 
test =  QAction('Test',mNu)
test.triggered.connect(action)
icon.setContextMenu(mNu)

它在xubuntu中有效。我似乎不知何故Ubuntu只希望在托盘中显示一个菜单。

答案 1 :(得分:1)

基于@Murdo和@eyllanesc答案,我在多个系统上测试了示例代码。 仅使用Python 3.5和pip3 install pyqt5进行全新安装。系统托盘图标激活信号为:

不工作:

  • Ubuntu 16.04 - Unity,PyQt 5.8和PyQt 5.5.1
  • Ubuntu 16.10 - Unity,PyQt 5.8和PyQt 5.7

工作:

  • Ubuntu 16.04 - Gnome,PyQt 5.8
  • Arch Linux - Gnome,PyQt 5.8
  • Kubuntu 16.10,KDE,PyQt 5.7
  • Xubuntu - 使用Stalonetray的Openbox

似乎示例代码是正确的,并且使用 Unity PyQT 中存在错误 - QSystemTrayIcon不发送单击系统托盘图标时发出activated信号。 我将在下周向河岸报告这个错误。

通过将QSystemTrayIcon分配给系统任务栏图标并检测QMenu信号,可以绕过

解决方案 QMenu().aboutToShow激活(点击)信号。这样,当单击托盘图标时,发送信号aboutToShow,然后显示菜单。它的结果并不完全相同,但似乎没有其他方法可以检测 Unity 上的系统托盘图标激活。感谢@Murdo的想法。简单的代码示例:

import sys
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QMenu
from PyQt5.QtGui import QIcon


def action():
    print('System tray icon clicked.')

app = QApplication(sys.argv)
icon = QSystemTrayIcon(QIcon('any_icon.png'), parent=app)
icon.show()

menu = QMenu(parent=None)
menu.aboutToShow.connect(action)
icon.setContextMenu(menu)

sys.exit(app.exec_())