[PyQt] Bug in QTableView.setModel()
Aaron Digulla
digulla at hepe.com
Tue Jan 8 12:12:10 GMT 2008
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.
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-collection
and
http://www.riverbankcomputing.com/Docs/PyQt4/html/qtextedit.html#setDocument
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).
Regards,
--
Aaron "Optimizer" Digulla a.k.a. Philmann Dark
"It's not the universe that's limited, it's our imagination.
Follow me and I'll show you something beyond the limits."
http://www.pdark.de/
More information about the PyQt
mailing list