[PyQt] Bug in QTableView.setModel()

Phil Thompson phil at riverbankcomputing.co.uk
Tue Jan 8 13:55:32 GMT 2008


On Tuesday 08 January 2008, Aaron Digulla wrote:
> Quoting Phil Thompson <phil at riverbankcomputing.co.uk>:
> > I'm happy to consider ways to make this more obvious (even if it's just a
> > better FAQ), but I'm not happy about departing from the Qt API and
> > introducing inconsistencies in fundamental behaviour.
>
> Then let me put it this way: If I wanted to care about who calls the
> dtor, I'd be using C++ and not Python. ;-)
>
> As a Python developer, I expect PyQt to behave like python code: As
> long as anyone (my code, PyQr or Qt) still has references to some
> object, the dtor must not be called, no matter what and PyQt as a
> *python* wrapper for Qt should follow the Python rules, not the Qt
> rules, especially not in a case where there is no conflict.

Then your expectations are misplaced. Are you seriously suggesting that PyQt 
somehow stops Qt calling a dtor?

> As I see it, managing the reference counter in setModel() is an easy
> fix, it doesn't break the Qt API and it makes PyQt behave like any
> Python expects. So what is the specific point not to do it?
>
> As for "ownership": Qt had to introduce this concept to avoid memory
> leaks. This is not necessary in Python (because Python handles this
> behind the scenes), so I suggest to ignore all "ownership"-style calls
> and/or wrap them in the Pyhton equivalent (to makes sure that objects
> aren't GC'd as long as someone still needs them). I'd guess that would
> fix most of the issues with little effort on your side plus reduce the
> amount of discussion and "I don't understand"-like mails considerably.
>
> The ultimate goal should be to have
>
>      edit.setDocument(QTextDocument(edit))
>
> and
>
>      edit.setDocument(QTextDocument())
>
> behave the same way: Make sure that QTextDocument() lives as long as
> edit needs it. Pseudocode:
>
>    setModel(model):
>      if model():
>         if isPython(model()):  model().refount--
>         elif model().owner == NULL: ShouldNotHappenException
>      if model:
>         if isPython(model):  model.refount++
>         else:
>           # Someone tried the Qt style -> avoid
>           model.owner = NULL # Owner is Python[1]
>           model = PyWrapper(model)
>           model.refount++
>      super.setModel(model)
>
> In this code, you could also print a warning if someone used
> QTextDocument(edit) or install a python GC object as the owner of the
> model which manages the relationships (face it: A model is not going
> to be used by more than 10..100 parents, so we could simply store
> everything in a map or list or something).
>
> Alternatively, you could add a thin wrapper for PyQt which works the
> Python way and print a warning if setModel() is called with a
> QTextDocument() which has no owner. Then users who don't want to care
> about dtor calling could use PyQTextDocument(), etc. instead.
>
> PS: Without your mail, I still wouldn't have a clue as to what is
> going on. There are some traces of information about this in the FAQ
> and elsewhere but they are far from easy to understand even after
> knowing your explanation. So if you refuse to fix the non-python
> behavior of PyQt, then please at least fix the documentation:
> http://www.riverbankcomputing.co.uk/pyqt/faq.php
> http://www.riverbankcomputing.com/Docs/PyQt4/pyqt4ref.html#garbage-collecti
>on and
> http://www.riverbankcomputing.com/Docs/PyQt4/html/qtextedit.html#setDocumen
>t
>
> These may seem clear to you but as a Python developer, I don't know
> why I should care that "[t]he parent QObject of the provided document
> remains the owner of the object." Only after reading all three
> documents, it becomes clear that "owner" means "who GCs the
> object/makes sure that it isn't GCd" (or calls the dtor).

Documentation patches welcome.

Phil


More information about the PyQt mailing list