String conversions

I will return to QCString later, as QString is used everywhere in Qt. All user-visible text is set using QStrings, and if a widget returns some text, it will return a QString as well. It should become clear that the only way to work comfortably with strings in Python and Qt is to have some automatic conversion between Python string objects and QStrings.

The conversion from a Python string to a QString is completely transparent. Any Qt class method that asks for a QString as an argument accepts any Python string (or Python Unicode string). The other way around isn't all that transparent, unfortunately. When you ask, for example, a QMultiLineEdit widget for its contents, you get a QString. If you try to use Python's regular expression engine on this object, of if you try to write it to a file, you will be surprised at the results:

Example 8-1. qstring1.py — conversion from QString to a Python string.

#
# qstring1.py - saving a QString to a file
#

from qt import *

# Construct a Python string

pyString = """Now is the summer of our sweet content,
Made o'er-cast winter by these Tudor clouds.
And I that am not shaped for black-faced war,
"""

# Construct a Qt QString

qtString=QString("""I that am rudely cast and want true majesty,
Am forced to fight,
To set sweet England free.
I pray to Heaven we fare well,
And all who fight us go to Hell.
""")

f=open("richard", "w+")
f.write(pyString)
f.flush()
f.write(qtString)
f.close()
      

If you run this script, you'll get the following output:

boud@calcifer:~/doc/opendoc/ch4 > python qstring1.py
Traceback (most recent call last):
  File "qstring1.py", line 26, in ?
    f.write(qtString)
TypeError: read-only character buffer, instance
boud@calcifer:~/doc/opendoc/ch4 >
    

There are good reasons for this behavior. Returning QStrings from widgets gives the developer access to all the neat Qt string handling functionality. A Qt string is mutable, in contrast to a Python string, and having the Qt QString makes it easier to change the contents in place. Lastly, returning a Qt string instead of a Python string avoids a somewhat costly conversion which might not be needed if all you want to do is to stuff the text in another Qt widget.

Of course, the downside is that if you want to treat a QString object as a Python string, you'll have to convert it yourself, using one of the Python built-in functions str() or unicode(). Adapting the previous script makes it work as expected:

Example 8-2. qstring2.py - second try of saving a QString to a file

#
# qstring2.py - saving a QString to a file
#

from qt import *

# Construct a Python string

pyString = """Now is the summer of our sweet content,
Made o'er-cast winter by these Tudor clouds.
And I that am not shaped for black-faced war,
"""

# Construct a Qt QString

qtString=QString("""I that am rudely cast and want true majesty,
Am forced to fight,
To set sweet England free.
I pray to Heaven we fare well,
And all who fight us go to Hell.
""")

f=open("richard", "w+")
f.write(pyString)
f.flush()
f.write(str(qtString))
f.close()
      

I don't need to show you screen output here — it just works. You will have to pay attention to what happens with the strings you receive from Qt widgets. If you want to write the contents to a file, database, or to mangle the string with Python modules, you will need to explicitly convert the QString object to Python strings. If you want to feed the string to another widget, you don't have to do anything.