QStringDecoder not callable in PySide6
It looks like a bug in PySide6. The returned object only has the inherited methods from QStringConverter, as can be seen by using dir
:
>>> dec = QtCore.QStringDecoder(QtCore.QStringConverter.Encoding.Utf16)
>>> for x in dir(dec):
... if x[0].islower(): print(x)
...
hasError
isValid
name
nameForEncoding
requiredSpace
resetState
state
So the decode methods are missing, and the TypeError
indicates that the ()
-operator overload is missing as well. The QStringEncoder
class has similar problems.
In PyQt6, everything works as expected:
>>> enc = QtCore.QStringEncoder(QtCore.QStringConverter.Encoding.Utf16)
>>> dec = QtCore.QStringDecoder(QtCore.QStringConverter.Encoding.Utf16)
>>> x = enc('text')
>>> x
PyQt6.QtCore.QByteArray(b't\x00e\x00x\x00t\x00')
>>> dec(x)
'text'
Of course, you don't really need to use these Qt classes, since the equivalent functionality already exists in Python:
>>> x = 'text'.encode('utf-16')
>>> x
b'\xff\xfet\x00e\x00x\x00t\x00'
>>> x.decode('utf-16')
'text'
Note that Python automatically prepends a BOM, whereas Qt requires an additional flag to get the same behaviour. To get a Qt-style callable object in Python, you can either use functools.partial or a lambda
:
>>> from functools import partial
>>> enc = partial(str.encode, encoding='utf-16')
>>> # or enc = lambda s: s.encode('utf-16')
>>> dec = partial(bytes.decode, encoding='utf-16')
>>> # or dec = lambda b: b.decode('utf-16')
>>> x = enc('text')
b'\xff\xfet\x00e\x00x\x00t\x00'
>>> dec(x)
'text'
NB: to convert a QByteArray
to a Python bytes
object, use bytes(qtbytearray)
or qtbytearray.data()
(see also: How to convert a QByteArray to a python string).