[PyQt] QVariant and Python list

Phil Thompson phil at riverbankcomputing.com
Fri May 30 15:20:17 BST 2008


On Friday 30 May 2008 3:11:01 pm Mark Summerfield wrote:
> On 2008-05-30, Phil Thompson wrote:
> > On Wednesday 28 May 2008 6:35:32 pm Laurent Léonard wrote:
> > > Hi,
> > >
> > > I read QList and QMap are not implemented in PyQt, because of the
> > > presence of Python lists and dictionaries.
> > >
> > > But how can I use QVariant to "encapsulate" Python lists and
> > > dictionaries ? When I try to do it I get the following error message :
> > > "TypeError: argument 1 of QVariant() has an invalid type"
> >
> > I'd be surprised if you got that error with the current version.
> >
> > There are a number of issues here which I'd like feedback on...
> >
> > The various QVariant ctors allow type convertors to have an effect, ie.
> > in SIP terms they don't have the /Constrained/ annotation. For example,
> > QVariant(const QStringList &) will accept a Python list of strings. I
> > think this is a mistake as QVariant([]) will be treated as an empty
> > QStringList but QVariant([0]) will be treated as a Python object.
> >
> > So I think every QVariant ctor that takes a Qt class should have
> > /Constrained/ applied.
> >
> > However that would then mean that QVariant([]) would now be treated as an
> > empty QList<QVariant> and still not as a Python object.
> >
> > For similar reasons QVariant({"abc": 0}) would be treated as a QMap, but
> > QVariant({1: 0}) would be treated as a Python object.
> >
> > Therefore I also want to drop support for QVariant(QList<>) and
> > QVariant(QMap<>) completely.
> >
> > The advantage is that anything that is not a fundamental type (int, float
> > etc) or a wrapped type will be treated as a Python object and can be
> > retrieved using toPyObject() - all very consistent.
> >
> > The disadvantages are that it is an incompatible change. It also becomes
> > impossible to create a QVariant(QList<>) or QVariant(QMap<>) from Python
> > (although I can't find a use case in Qt). I could add fromQVariantList()
> > and fromQVariantMap() methods to get round the second problem.
>
> I have a rather more controversial suggestion (so maybe for Python
> 3/PyQt). Why not kill QVariant and QStringList and QString altogether!
> Trolltech did just that with Jambi (Java/Qt), for which they use the
> native Java Object and Java String, etc.
>
> No matter how carefully PyQt honours the buffer API you still hit nasty
> problems from time to time. For example, if you use the gzip module with
> a QString filename you get a corrupt file; but it works perfectly with a
> unicode or str filename. But the point is that if PyQt only used unicode
> (str in Python 3) and bytes (for QByteArray) and object (for QVariant),
> none of those kind of subtle problems would arise. It would also put an
> end to having to know which kind of string you have and converting
> between the two kinds.
>
> Of course QString has some methods that unicode/str doesn't have. That
> was also true of Java String and Trolltech solved that by providing some
> static methods (that accept and return Java Strings) to fill the gaps;
> the same could be done in PyQt.
>
> My 2c;-)

That's what I want to do for Py3 (or PyQt5 for Py2) but is too radical for the 
moment.

Phil



More information about the PyQt mailing list