[PyQt] QVariant and Python list

Phil Thompson phil at riverbankcomputing.com
Fri May 30 15:23:04 BST 2008


On Friday 30 May 2008 3:14:43 pm Laurent Léonard wrote:
> Le vendredi 30 mai 2008 à 13:38, Phil Thompson a écrit :
> > 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.
> >
> > Comments?
> >
> > Phil
> >
> > _______________________________________________
> > PyQt mailing list    PyQt at riverbankcomputing.com
> > http://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
> Some interesting tests about QVariants and lists...
>
> >>> list = ["one", "two", "three"]
> >>> list2 = [1, 2, 3]
> >>> print QtCore.QVariant(list).toList()[0].toString()
>
> one
>
> >>> print QtCore.QVariant(list2).toList()[0].toString()
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: argument 1 of QVariant() has an invalid type
>
> >>> list2 = [QtCore.QVariant(1), QtCore.QVariant(2), QtCore.QVariant(3)]
> >>> print QtCore.QVariant(list2).toList()[0].toString()
>
> 1
>
> And about QVariants and dictionaries....
>
> >>> dict = {"blahKey": QtCore.QVariant("blahBlahValue")}
> >>> print QtCore.QVariant(dict).toMap()["blahKey"].toString()
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> KeyError: 'blahKey'
>
> >>> print
> >>> QtCore.QVariant(dict).toMap()[QtCore.QString("blahKey")].toString()
>
> blahBlahValue
>
> So for lists encapsulated into QVariant, the list have to contain strings,
> QStrings or QVariants. And for dictionaries encapsulated into QVariant, the
> keys have to be strings or QStrings and the values strings, QStrings or
> QVariants. But in both cases, QVariant use QStrings to store strings.

Yes, when there is additional information (ie. the type of a list element) 
PyQt can do "the right thing". The problem arises with the empty list.

Phil



More information about the PyQt mailing list