Il giorno ven, 21/01/2011 alle 22.01 +0100, Erik Janssens ha scritto: > Hello Nicola, > > I'm not sure what happens when you reset the parent of a widget to None, > (wether it then transfers ownership back to python).
it works > > If you get that run-time error, this means that qt deleted the widget, this > random effect might have been triggered by the garbage collector. > I cannot reproduce the error systematically it never happened during my tests, a customer reported to me this error, I added the try except statment and noone reported any problem > you can verify this by disabling the garbage collector and see if > it still happens : > > import gc > gc.disable() > > I'm don't know if this trick with reparenting works, but it looks like > a good trick to have speedups ?? attacched is an updated sample with a time.sleep in __init__, so when the dialog is loaded from the cache the difference is noticeable. if I understand your article (http://downloads.conceptive.be/downloads/camelot/doc/sphinx/build/advanced/development.html) my sample should not work, I'm setting the parent of a qt object to None, so qt should delete it, and I'm keeping a reference to the python object (this seems the opposite of what you suggets). Please play with the sample, for example you can: - click on "Open dialog", the first time you'll wait about 5 seconds - when you close the dialog it's parent is setted to None, and the global object is populated - click "Change widget", and click "Open dialog" again (from a different widget), this time the dialog is loaded from the cache - you can repeat the sequence, or try any other order this works, but probably it should not work ... Nicola > > Erik > > On Fri, Jan 21, 2011 at 10:21 AM, Mailing List SVR > <li...@svrinformatica.it> wrote: > > Hi Erik, > > > > attacched is a small sample of what I'm doing in my app, I have a dialog > > that require some time to open, to speed up the things I store it in a > > global object and use this global object to reopen the dialog, > > > > this seems to work, I'm reusing the same dialog from different central > > widget, some times (I'm unable to reproduce) I see in the logs: > > > > RuntimeError: underlying C/C++ object has been deleted > > > > so I added a try except when I open the dialog, until today noone > > reported segfault, what do you think about this usage? > > > > thanks > > Nicola > > > > Il giorno ven, 21/01/2011 alle 08.47 +0100, Erik Janssens ha scritto: > >> Hi, > >> > >> I wrote some general documentation around these > >> issues, with regard to Camelot development, but > >> it might be of use to others as well : > >> > >> http://downloads.conceptive.be/downloads/camelot/doc/sphinx/build/advanced/development.html > >> > >> all remarks/corrections are welcome. > >> > >> Regards, > >> > >> Erik > >> > >> On Thu, 2011-01-20 at 10:22 +0100, Mailing List SVR wrote: > >> > Ok, in a my pyqt app (I'm still using pyqt-4.7.x), I have a dialog that > >> > require much time to open so I keep a reference to it in a app global > >> > variable and I use this reference to reopen the dialog after the first > >> > time. This seems to work and the dialog open much quicker, however in > >> > some undeterminated cases I get: > >> > > >> > RuntimeError: underlying C/C++ object has been deleted > >> > > >> > when I get this error I recreate the dialog and update the global > >> > reference, > >> > > >> > can you please explain the right way to keep a reference in python to a > >> > qt object? > >> > > >> > thanks > >> > NIcola > >> > > >> > > >> > Il giorno mer, 19/01/2011 alle 23.47 +0100, Erik Janssens ha scritto: > >> > > there was a change in sip/pyqt from 4.8.1 to 4.8.2 regarding > >> > > the detection of objects deleted by qt but still referenced in > >> > > python (which is the case here). in 4.8.1 sip/pyqt tried to > >> > > detect this to avoid segfaults. this detection however brought > >> > > other issues with it, therefor the detection was turned off again > >> > > in 4.8.2 > >> > > > >> > > the solution is not to keep references in python of objects > >> > > owned by qt when they might get deleted. > >> > > > >> > > On Wed, Jan 19, 2011 at 12:36 PM, Mailing List SVR > >> > > <li...@svrinformatica.it> wrote: > >> > > > I can confirm the segfault: > >> > > > > >> > > > - linux, kernel 2.6.36 > >> > > > - python 2.7.1 > >> > > > - pyqt 4.8.2 > >> > > > - qt 4.7.1 > >> > > > > >> > > > works fine with PySide, > >> > > > > >> > > > Nicola > >> > > > > >> > > > > >> > > > Il giorno mer, 19/01/2011 alle 08.36 +0100, Vicent Mas ha scritto: > >> > > >> 2011/1/18 Nick Gaens <m...@nickgaens.com>: > >> > > >> > - Win7 64bit > >> > > >> > - Python 2.6.6 (r266:84297, Aug 24 2010, 18:46:32) [MSC v.1500 32 > >> > > >> > bit > >> > > >> > (Intel)] on win32 > >> > > >> > - Qt v4.7.0 > >> > > >> > - PyQt GPL v4.8.1 for Python v2.6 > >> > > >> > Result: no crashes, works like a charm.. > >> > > >> > > >> > > >> > >> > > >> Hi, > >> > > >> > >> > > >> I get the crash also on Windows Vista 32bit (again Python 2.6 and > >> > > >> PyQt 4.8.2) > >> > > >> > >> > > >> Vicent > >> > > >> > >> > > > > >> > > > _______________________________________________ > >> > > > PyQt mailing list PyQt@riverbankcomputing.com > >> > > > http://www.riverbankcomputing.com/mailman/listinfo/pyqt > >> > > > > >> > > _______________________________________________ > >> > > PyQt mailing list PyQt@riverbankcomputing.com > >> > > http://www.riverbankcomputing.com/mailman/listinfo/pyqt > >> > > >> > >> > > > _______________________________________________ > PyQt mailing list PyQt@riverbankcomputing.com > http://www.riverbankcomputing.com/mailman/listinfo/pyqt
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui, QtCore import time class AppGlobal(object): global_dlg=None app_global=AppGlobal() class TestDialog(QtGui.QDialog): def __init__(self,parent=None): super(TestDialog,self).__init__(parent) time.sleep(5) self.setWindowTitle('Reference Dialog') self.setGeometry(200, 200, 150, 120) self.test_button = QtGui.QPushButton('Close dialog', self) self.connect(self.test_button, QtCore.SIGNAL('clicked()'),self.accept) def onClose(self): print self.parent() if app_global.global_dlg is None: print 'keep a dialoog reference in app_global' app_global.global_dlg=self self.setParent(None) def accept(self): self.onClose() QtGui.QDialog.accept(self) def reject(self): self.onClose() QtGui.QDialog.reject(self) class TestWidget(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.setGeometry(300, 300, 250, 150) self.test_button = QtGui.QPushButton('Open dialog', self) self.test_button.setGeometry(10, 10, 200, 35) self.test_button1 = QtGui.QPushButton('Change widget', self) self.test_button1.setGeometry(10, 60, 200, 35) self.connect(self.test_button, QtCore.SIGNAL('clicked()'),self.onClick) self.connect(self.test_button1, QtCore.SIGNAL('clicked()'),self.onClick1) def onClick(self): if not app_global.global_dlg: print 'new dialog created' dlg=TestDialog(self) dlg.exec_() else: try: print "open saved dialog" #app_global.global_dlg.setParent(self) app_global.global_dlg.exec_() except Exception,e: print e app_global.global_dlg=None dlg=TestDialog(self) dlg.exec_() def onClick1(self): #print 'change widget from TestWidget' self.parent().setCentralWidget(AnotherWidget()) class AnotherWidget(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.setGeometry(300, 300, 250, 150) self.test_button = QtGui.QPushButton('back', self) self.test_button.setGeometry(10, 60, 200, 35) self.test_button1 = QtGui.QPushButton('Open Dialog', self) self.test_button1.setGeometry(10, 10, 200, 35) self.connect(self.test_button, QtCore.SIGNAL('clicked()'),self.onClick) self.connect(self.test_button1, QtCore.SIGNAL('clicked()'),self.onClick1) def onClick(self): #print 'change widget from AnotherWidget' w=TestWidget() self.parent().setCentralWidget(w) def onClick1(self): if not app_global.global_dlg: print 'new dialog created' dlg=TestDialog(self) dlg.exec_() else: try: print "open saved dialog" #app_global.global_dlg.setParent(self) app_global.global_dlg.exec_() except Exception,e: print e app_global.global_dlg=None dlg=TestDialog(self) dlg.exec_() class MainApp(QtGui.QMainWindow): def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) self.setGeometry(300, 300, 250, 150) self.setWindowTitle('Reference Demo') t=TestWidget() self.setCentralWidget(t) app = QtGui.QApplication(sys.argv) m = MainApp() m.show() sys.exit(app.exec_())
_______________________________________________ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt