[PyKDE] Update on QStrings and PyQt4
Phil Thompson
phil at riverbankcomputing.co.uk
Sun Oct 23 13:11:37 BST 2005
Thanks for all the comments on QStrings in PyQt4. I thought I'd summarise my
current thinking...
There seem to be four aspects to the problem...
Functionality
Does QString have any functionality over Python unicode objects that would be
missed? I haven't seen any argument that there is.
Mutability
QStrings are mutable, unicode objects aren't. I haven't found anywhere in the
Qt API where this would be an issue. Any function that returns a reference to
a QString returns a const reference. I don't know if this is also true of
KDE.
Performance
Without QString support unicode objects have to be converted to QStrings when
passed as arguments and converted back when returned as results. The
following would be much less efficient than it is now:
foo.setText(bar.text())
There is a performance optimisation that could be done where QString was
mapped to a sub-type of unicode that kept the original QString in case it was
ever needed again. The above example would still have the conversion to
unicode on the return from text(), but the conversion back to a QString as
the setText() argument would be avoided. However I don't believe that this is
a realistic example and my feeling is that in 99% of cases performance will
not be an issue. It is still a risk though.
Philosophy
This is the real problem. Is the typical PyQt user going to be more familiar
with Python string handling or Qt string handling? How closely should PyQt
implement the Qt API?
Historically PyQt has followed the Qt API closely, but they are not identical.
QList type classes have always been implemented as Python lists - only when
the Qt class has implemented additional functionality (like QStringList) has
it been wrapped. When PyQt was first released, QString was much more
functional that Python v1.5 strings.
One option might be to make QStrings behave much more like unicode objects.
This involves implementing the Python API in QString (ie. lots of
%MethodCode) and improving the interoperability between QStrings and unicode
objects.
A lot of interoperability improvements have been made in current PyQt3
snapshots. I've just implemented the buffer interface for QString and the
following now work:
f = open(QString("Qt"), "r") "foobar".find(QString("bar"))
"fooxxx".replace(QString("xxx", QString("bar"))
I've already mentioned that the following also now work:
s = "Py" + QString("Qt")
s = "Py"; s += QString("Qt")
Unfortunately, this still doesn't work:
QString("foo") in "foobar"
I think this is actually a feature/bug in Python - for this operation, unlike
other methods like find(), replace() etc., the buffer interface isn't used
for some reason. I don't know if other string operations have a similar
problem.
As a test of the improvements I tried removing all the explicit str() calls in
one of my apps. (Like a lot of people I am in the habit of getting rid of
QStrings at the earliest opportunity.) I immediately fell foul of the "in"
problem.
Conclusions
If it wasn't for the "in" problem I would probably favour using duck typing to
make QStrings look like Python unicode objects. However I think the operation
is so common that it is a showstopper.
Otherwise my preference is to drop QStrings (and QByteArray, QLatin1String,
QChar and QLatin1Char). Before PyQt4 becomes usable I will add a
configuration option that will enable those classes to allow people to
evaluate both approaches. It will then be up to people who need QString
support to prove that that is the case. By default they will go. The
configuration option will be removed before the final PyQt4 release.
Phil
More information about the PyQt
mailing list