On 16/08/10 18:27, danny wrote:
Howdy,

I have run into this curious problem that I think is caused by a memory leak
or improper reference counting related to toolbars in QMainWindow.removeToolBar.
The problem appears when you remove a toolbar but keep an instance variable
maintaining a reference to the toolbar. I am aware that removeToolBar only
hides the toolbar and does not delete it. I also am aware that the following
code may seem foolish, but it does show the bug. The code below is a minimal
example demonstrating the problem. It is 34 lines long. Simply run the app, and
close via the close box. The app will not close gracefully, but rather seg 
fault.
This has been validated on windows and Linux.  I don't believe the following
code is doing anything stupid enough to justify a seg fault. The problem
disappears is you remove the instance reference to the toolbar
(self.editToolBar = editToolBar). Notice that the code is intended to reside
within an SDI framework app like Mark Summerfield uses in his excellent PyQT
book. The instances variables probably keep additional references around that
are part of the problem. Explicitly removing the attribute, gets rid of the
problem.

Included below is the source code. Please let me know if this is a bug or
my own stupidity.

I am running python 2.5.1, pyqt 4.7.3

thanks,

Danny

#%<--------------------------------------------
import sys
from PyQt4 import QtGui,  QtCore,  QtSql

def isAlive(qobj):
     import sip
     try:
         sip.unwrapinstance(qobj)
     except RuntimeError:
         return False
     return True

class MyApp(QtGui.QMainWindow):
     NextId = 1
     Instances = set()

     def __init__(self, parent=None):
         super(MyApp, self).__init__(parent)
         self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
         MyApp.Instances.add(self)
         self.editToolBar = self.addToolBar("Edit")
         self.removeToolBar(self.editToolBar)
         # delattr(self,  'editToolBar') # this gets rid of the seg fault
         self.destroyed.connect(MyApp.updateInstances)
         self.setCentralWidget(QtGui.QWidget())

     @staticmethod
     def updateInstances(qobj):
         MyApp.Instances = set([window for window \
                 in MyApp.Instances if isAlive(window)])

if __name__=='__main__':
     application = QtGui.QApplication(sys.argv)
     MyApp().show()
     application.exec_()

i don't think it is a bug. the real problem is with how the toolbar is being created, not with how it's being destroyed.

try something like this:

import sys
from PyQt4 import QtGui,  QtCore

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self._toolbar = QtGui.QToolBar('Edit', self)
        self.addToolBar(self._toolbar)
        self.removeToolBar(self._toolbar)

if __name__=='__main__':
    app = QtGui.QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

_______________________________________________
PyQt mailing list    [email protected]
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Reply via email to