2017-04-27 54 views
1

我试图在PyQT5程序中单击系统托盘图标时打印文本。我尝试将PyQT5 QSystemTrayIcon激活的信号(单击系统托盘图标时发出的)连接到自定义方法,但未调用该方法。 下面是简单的例子: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个插槽。但是,当单击系统托盘图标时,它不会执行任何操作。

问题:信号连接不正确,还是信号根本没有发出?

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

+0

我已经尝试过,它运行良好。我使用Arch Linux,PyQt5.8,Qt5.8和gnome作为桌面管理器。 – eyllanesc

+0

@eyllanesc感谢您试用和详细信息。我忘记提及我有_Unbuntu_,_Unity_, 而不是_Gnome_,所以这使我进行了一些测试,我认为_Unity_上的_PyQT_存在一个错误。更多信息在我的答案下面。 –

回答

0

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

不工作:

  • 的Ubuntu 16.04 - 团结,PyQt的5.8和PyQt的5.5.1
  • 的Ubuntu 16.10 - 团结,PyQt的5.8和5.7的PyQt

工作:

  • 的Ubuntu 16.04 - 侏儒,PyQt的5.8
  • Arch Linux的 - 侏儒,PyQt的5.8
  • 的Kubuntu 16.10,KDE,PyQt的5。7
  • 的Xubuntu - Openbox的与Stalonetray

好像示例代码是正确的,是有臭虫PyQt的使用统一 - QSystemTrayIcon不发送activated信号时,系统托盘图标被点击。 我将在下周向河岸报告bug。

SOLUTIONQSystemTrayIcon激活(点击)信号可以通过分配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_()) 
+0

我与PyQt 5.9和Lubuntu 16.04有同样的问题 – sunyata

0

您的示例在Xubuntu中使用stalonetray的openbox工作得很好。 但是,在Xubuntu本身并不适用! 但是,当我又补上一句:

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

它曾在Xubuntu的。我似乎不知道Ubuntu只希望在托盘中显示一个菜单。

+0

问题是我点击系统托盘图标时需要调用'action()',但是上面的例子 在菜单项被点击时发送信号。然而,它在_Xubuntu_ 上工作的事实帮助我进行了测试,并且您告诉我如何使用QMenu()来绕过问题 - 我目前添加的答案更多。非常感谢你! –