[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