PyQt4 托盘图标显示 QLabel 时出现问题
当以下代码运行时,托盘应用程序可以在屏幕中间弹出 AboutWindow QLabel 对象。但是,当关闭此屏幕时,整个应用程序将关闭,没有任何错误(托盘图标消失,控制台日志没有显示任何错误)。
import sys
from PyQt4 import QtGui, QtCore
class AboutWindow(QtGui.QLabel):
def __init__(self, parent=None):
QtGui.QLabel.__init__(self, parent=parent)
self.setText("""
Huge text goes here
""")
class SystemTrayIcon(QtGui.QSystemTrayIcon):
def __init__(self, icon, parent=None):
QtGui.QSystemTrayIcon.__init__(self, icon, parent)
menu = QtGui.QMenu(parent)
self.createMenuActions(menu)
self.setContextMenu(menu)
# I've tried using the same parent as QSystemTrayIcon,
# but the label is not shown.
# self.aboutWindow = AboutWindow(parent=parent)
self.aboutWindow = AboutWindow(parent=None)
def createMenuActions(self, menu):
exitAction = QtGui.QAction("Exit", menu)
configureAppAction = QtGui.QAction("Configure Application", menu)
aboutAction = QtGui.QAction("About", menu)
self.connect(configureAppAction, QtCore.SIGNAL('triggered()'), self._configureApp)
self.connect(aboutAction, QtCore.SIGNAL('triggered()'), self._showAbout)
self.connect(exitAction, QtCore.SIGNAL('triggered()'), self._exitApp)
self.addActionsToMenu(menu, configureAppAction, aboutAction, exitAction)
def addActionsToMenu(self, menu, *args):
for action in args:
menu.addAction(action)
def _configureApp(self): pass
def _showAbout(self):
self.aboutWindow.show()
def _exitApp(self):
sys.exit(0)
def main():
app = QtGui.QApplication(sys.argv)
widget = QtGui.QWidget()
# I'm passing a widget parent to QSystemTrayIcon as pointed out in:
# http://stackoverflow.com/questions/893984/pyqt-show-menu-in-a-system-tray-application
trayIcon = SystemTrayIcon(QtGui.QIcon("icon.xpm"), widget)
trayIcon.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
正如代码中所指出的,我尝试为托盘图标和 AboutWindow 对象设置相同的父级,但这不起作用(标签未显示)。我也尝试过子类化 QMainWindow,但出现了相同的效果。
我想了解当窗口和图标都不共享相同父级时从 QSystemTrayIcon 打开新窗口时这是否是默认行为,以及是否有解决方法。
谢谢。
When the following code runs, the tray application can pop-up the AboutWindow QLabel object in the middle of screen. But when closing this screen, the whole application is shutdown with no errors (the tray icon disappears and the console log shows no error whatsoever).
import sys
from PyQt4 import QtGui, QtCore
class AboutWindow(QtGui.QLabel):
def __init__(self, parent=None):
QtGui.QLabel.__init__(self, parent=parent)
self.setText("""
Huge text goes here
""")
class SystemTrayIcon(QtGui.QSystemTrayIcon):
def __init__(self, icon, parent=None):
QtGui.QSystemTrayIcon.__init__(self, icon, parent)
menu = QtGui.QMenu(parent)
self.createMenuActions(menu)
self.setContextMenu(menu)
# I've tried using the same parent as QSystemTrayIcon,
# but the label is not shown.
# self.aboutWindow = AboutWindow(parent=parent)
self.aboutWindow = AboutWindow(parent=None)
def createMenuActions(self, menu):
exitAction = QtGui.QAction("Exit", menu)
configureAppAction = QtGui.QAction("Configure Application", menu)
aboutAction = QtGui.QAction("About", menu)
self.connect(configureAppAction, QtCore.SIGNAL('triggered()'), self._configureApp)
self.connect(aboutAction, QtCore.SIGNAL('triggered()'), self._showAbout)
self.connect(exitAction, QtCore.SIGNAL('triggered()'), self._exitApp)
self.addActionsToMenu(menu, configureAppAction, aboutAction, exitAction)
def addActionsToMenu(self, menu, *args):
for action in args:
menu.addAction(action)
def _configureApp(self): pass
def _showAbout(self):
self.aboutWindow.show()
def _exitApp(self):
sys.exit(0)
def main():
app = QtGui.QApplication(sys.argv)
widget = QtGui.QWidget()
# I'm passing a widget parent to QSystemTrayIcon as pointed out in:
# http://stackoverflow.com/questions/893984/pyqt-show-menu-in-a-system-tray-application
trayIcon = SystemTrayIcon(QtGui.QIcon("icon.xpm"), widget)
trayIcon.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
As pointed out in the code, I've tried setting the same parent for the tray icon and the AboutWindow object, but that didn't work (the label is not shown). I have also tried subclassing QMainWindow, but the same effect occured.
I would like to understand if that's the default behavior when opening a new window from QSystemTrayIcon when neither the window and the icon share the same parent, and if there's a workaround for this matter.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,我想我对这个问题不太清楚,但我找到了一个简单的解决方案。
Qt 有一个方法可以捕获分派到小部件的关闭事件 (http://doc.qt.nokia.com/4.6/qwidget.html#closeEvent)。您可以在 QWidget 子类中重写此方法以防止小部件关闭(在我的所有测试中,这将关闭整个应用程序)并仅隐藏它。下面的代码显示了我在代码中所做的更改以使其正常工作:
Alright, I guess I wasn't too clear about the problem, but I found a simple solution.
Qt has a method that captures the close event dispatched to a widget (http://doc.qt.nokia.com/4.6/qwidget.html#closeEvent). You can, in your QWidget subclass, rewrite this method to prevent the widget from closing (which, in all my tests, would close the whole application) and only hide it. The code below shows what I've changed in my code to make it work:
出现此问题的原因是,当您关闭“唯一”窗口时,Qt 错误地认为您要退出应用程序。
你的(Kaos12)答案是一个丑陋的修复恕我直言,有时你真的想关闭这些东西(这与隐藏它不同)。
正确的方法是
在该代码的第 50 行之后(“创建”应用程序之后)添加以下行来禁用此行为。该指令将告诉 Qt 即使所有窗口都关闭也不要退出应用程序。
This problem occurs because when you close the 'only' window, Qt erroneously thinks you want to quit the application.
Your (Kaos12) answer is an ugly fix imho, sometimes you really want to close the stuff (which isn't the same as hiding it).
The proper way to do that is to disable this behaviour by adding the line:
after the line 50 in that code (after 'creating' the application). This instruction will tell Qt not to quit the application even when all the windows are closed.