【发布时间】:2011-03-13 16:11:44
【问题描述】:
我的代码本身实际上没有问题,但是如果我添加我的程序以在启动时运行(即每次用户登录时),它无法创建托盘图标,因为当时它试图,任务栏尚未完全创建/初始化。有解决方案吗?现在我正在考虑以 10 秒的间隔重试 10 次。
【问题讨论】:
-
您的目标是哪种操作系统/桌面环境?
-
这个问题发生在 Ubuntu Linux 上。
我的代码本身实际上没有问题,但是如果我添加我的程序以在启动时运行(即每次用户登录时),它无法创建托盘图标,因为当时它试图,任务栏尚未完全创建/初始化。有解决方案吗?现在我正在考虑以 10 秒的间隔重试 10 次。
【问题讨论】:
这当然是一种竞争条件。重试是个好主意,是的,但我会延迟。启动应用程序,但在尝试连接任务栏之前使用 QTimer::singleShot() 延迟 5 秒(或其他任何时间)。如果您想在那之后重试(这可能是个好主意),请延迟更长的时间(因为立即重试也可能不会成功,因为重试速度太快了)。
【讨论】:
引自http://developer.qt.nokia.com/doc/qt-4.8/qsystemtrayicon.html(注意第二段):
“要检查用户桌面上是否存在系统托盘,请调用 QSystemTrayIcon::isSystemTrayAvailable() 静态函数。” ...
“如果系统托盘在构建系统托盘图标时不可用,但稍后可用,如果图标可见,QSystemTrayIcon会自动在系统托盘中添加应用程序条目。”
Moca 是对的,它应该按照文档工作。但是,这不是由于 Qt 中的bug 61898。
解决方法是使用isSystemTrayAvailable() 等待系统托盘可用。作为Wes Hardaker suggests,您可以每隔几秒钟尝试使用QTimer::singleShot(),直到系统托盘可用为止。
请注意,如果您在系统托盘可用时show()您的托盘图标,即使系统托盘被移除并创建了一个新托盘(如文档所述),它也将始终再次显示,因此您只需要第一次做对。
我用的是 PyQt5,我换了
self.show()
与
self._show_when_systray_available()
def _show_when_systray_available(self):
"""Show status icon when system tray is available
If available, show icon, otherwise, set a timer to check back later.
This is a workaround for https://bugreports.qt.io/browse/QTBUG-61898
"""
if self.isSystemTrayAvailable():
self.show()
else:
QtCore.QTimer.singleShot(1000, self._show_when_systray_available)
我只能看到一个(不太可能)失败的情况:在isSystemTrayAvailable() 返回true 之后和您的状态图标显示之前的一小段时间内删除系统托盘的竞争条件。
编辑:根据the bugtracker,此问题已在 5.12.4 中修复。
【讨论】: