I have some problems with PySide and it's internal cleanup process. It seems that my PySide objects are deleted before I really use them. The following example is maybe not the best one, but it was easiest one to simply and reproduce the same error. The only difference is, that in the Application I use, the API gives me a wrapInstance
function to get the QMainWindow
(each time with a new ID). But the Error is the same.
import sys
from PySide import QtGui
class AnyApplication(QtGui.QMainWindow):
def __init__(self):
super(AnyApplication, self).__init__()
self.initUI()
def initUI(self):
self._menuBar = self.menuBar()
for dummy in ["File","Edit","Help"]:
self._menuBar.addMenu(dummy)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('MenuTest')
class MenuBar(object):
def __init__(self, qMenuBar):
self.menuBar = qMenuBar
def AddMenu(self, name):
result = self.GetMenu(name)
if result: return result
else:
new = self.menuBar.addMenu(name)
print "Created: ",name , new
result = Menu(new, name)
return result
def GetMenu(self, name):
print "\nSearch for: ",name
for action in self.menuBar.actions():
if action.text()==name:
print "Found: ",name , action.menu().actions()
return Menu( action.menu(), name)
return None
class Menu(object):
def __init__(self, menu=None, name=None):
self.menu = menu
self.name = name
def AddMenu(self, name):
# print "Name: ",name
result = self.GetMenu(name)
if result: return result
else:
new = self.menu.addMenu(name)
print "Created: ",name , new
result = Menu(new, name)
return result
def GetMenu(self, name):
print "\nSearch for: ",name
for action in self.menu.actions():
if action.text()==name:
print "Found: ",name , action.menu()
return Menu(action.menu(), name)
return None
if __name__ == '__main__':
# Launch Application
app = QtGui.QApplication(sys.argv)
anyApp = AnyApplication()
anyApp.show()
# Access Application with API
print "\n## 1st ####################"
apiMenu = MenuBar(anyApp.menuBar()).AddMenu("API")
anMenu = apiMenu.AddMenu("Analyse")
print "\n## 2nd ####################"
apiMenu = MenuBar(anyApp.menuBar()).AddMenu("API")
exMenu = apiMenu.AddMenu("Execute")
sys.exit(app.exec_())
The result:
## 1st ####################
Search for: API
Created: API <PySide.QtGui.QMenu object at 0x00000000031E7488>
Search for: Analyse
Created: Analyse <PySide.QtGui.QMenu object at 0x00000000031E7408>
## 2nd ####################
Search for: API
Found: API [<PySide.QtGui.QAction object at 0x00000000031E7588>]
Search for: Execute
Traceback (most recent call last):
File "C:/test/qtMenu.py", line 92, in <module>
exMenu = apiMenu.AddMenu("Execute")
File "C:/test/qtMenu.py", line 61, in AddMenu
result = self.GetMenu(name)
File "C:/test/qtMenu.py", line 71, in GetMenu
for action in self.menu.actions():
RuntimeError: Internal C++ object (PySide.QtGui.QMenu) already deleted.
How do I get rid of the cleanup process from PySide? Or do I have to define the QObjects in a different way to leave them alive?
If you change the PySide import to from PyQt4 import QtGui
you will see that it works fine with PyQt.