[PyQt] Problem/Bug with QSystemTrayIcon and QMenu

Adam Batkin adam at batkin.net
Thu Sep 6 14:49:12 BST 2007


Phil Thompson wrote:
> On Thursday 06 September 2007, Adam Batkin wrote:
>> I have reduced my problem down to just a few lines of code, but the basic
>> summary is that when trying to add a QMenu to a QSystemTrayIcon
>> (tray.setContextMenu()), sometimes the menu deletes itself.
>>
>> Here is some sample code:
>> # -----------------------------
>> def itdied ():
>>          print "died"
>>
>> def buildMenu ():
>>          menu = QtGui.QMenu()
>>          menu.addAction("Exit", lambda: exit(0))
>>          QtCore.QObject.connect(menu,QtCore.SIGNAL("destroyed()"),itdied)
>>          return menu
>>
>> app = QtGui.QApplication([])
>>
>> tray = QtGui.QSystemTrayIcon()
>>
>> QtCore.QObject.connect(tray,QtCore.SIGNAL("activated(QSystemTrayIcon::Activ
>> ationReason)"),activated)
>>
>> tray.setContextMenu(buildMenu())
>> print "menu=%s" % (tray.contextMenu())
>>
>> tray.show()
>> app.exec_()
>> # -----------------------------
>>
>> If I run the above, I get the following output:
>> died
>> menu=None
>>
>> Which means that the menu's destroyed() signal was fired, and
>> tray.contextMenu() returned None (even though it was just set).
>>
>> If I replace the tray.setContextMenu(buildMenu()) line with:
>> menu = buildMenu()
>> tray.setContextMenu(menu)
>>
>> then my output is:
>> menu=<PyQt4.QtGui.QMenu object at 0xb7f1c8ac>
>>
>> and "died" isn't printed until the menu is actually destroyed (on program
>> exit), which all makes perfect sense since menu is set to an actual object.
>>
>> Thoughts?
> 
> Your "workaround" is the correct thing to do (or give the menu a parent). 
> setContextMenu() doesn't take ownership of the menu.

Hmm, neither the PyQt4 or the Qt docs mention this fact, though it makes sense that 
QSystemTrayIcon wouldn't take ownership since QSystemTrayIcon isn't a QWidget (i.e. I 
can't pass the tray icon into the QMenu's constructor). That said, from a 
pythonic-perspective I would think that the tray might at least maintain a reference to it 
which would prevent it from being deleted.

Ahh well, that at least explains exactly why that is happening, even if it isn't a perfect 
solution.

Thanks!

-Adam Batkin




More information about the PyQt mailing list