[PyQt] Conversion from QML

B. B. thebbzoo at gmail.com
Wed Jan 7 14:24:15 GMT 2015

So the code would be something like :

# objects... like dicts

d = myQJSObject

if d[ "spices" ].toString() == "pebber" :
    more = "yes please"

if d.property( "spices" ).toString() == "pebber" :
     more = "yes please"

# or for arrays

a = myQJSArray
nbr1 , nbr2 = a[0].toNumber() , a[2].toNumber()


nbr1, nbr2 = a.property( 0 ).toNumber() , a.property( 1 ).toNumber()

Someone might then expect it could work with string???
( which would fail.. )

s  = myQJSString
firstLetter = s[0]


I think it looks better with the mapping protocol, but personally in my
code, I would always use the property function. This is only because I know
my memory, so when I would have to fix an error 7 months after writing,
I would probably start calling the items() or start iterate..... :-)

What I did was making a convert function, converting QJSValues to about the
same form as the output had before....
( unpack all QJSValues ... ) ...

My very untested version of the convert function is below, if someone
should need something like that :

Best Regards

Brian ..

--------------------- 8< -----------------

from PyQt5.QtQml import QJSValueIterator, QJSValue
from functools import partial

def pyFyQJSValue( qjsValue, instance = None ):

    if qjsValue.isString():
        return qjsValue.toString()
    elif qjsValue.isNumber():
        return qjsValue.toNumber()
    elif qjsValue.isArray():
        return [ pyFyQJSValue( qjsValue.property( idx ) )
                 for idx in range( int( qjsValue.property( "length"
).toNumber() ) ) ]
    elif qjsValue.isCallable():
        return partial( _call, qjsValue, instance )
    elif qjsValue.isQObject():
        return qjsValue.toQObject()
    elif qjsValue.isObject():
        return dict( ( k, pyFyQJSValue( v, instance = qjsValue ) ) for k, v
in iterJSObjectItems( qjsValue ) )
    elif qjsValue.isBool():
        return qjsValue.toBool()
    elif qjsValue.isNull():
        return None
    elif qjsValue.isRegExp():
        return qjsValue.toVariant()
    elif qjsValue.isBool():
        return qjsValue.toBool()
    elif qjsValue.isDate():
        return qjsValue.toDateTime()
    elif qjsValue.isUndefined():
        return None
    elif qjsValue.isVariant():
        return qjsValue.toVariant()

    raise Exception( "sorry, you need to update the pyFyQJSValue to convert
this unhandled value" )

def iterJSObjectItems( jsObject ):
    if not jsObject.isObject():
    it = QJSValueIterator( jsObject )
    while it.hasNext():
        yield it.name(), it.value()

def _call( qjsValue, instance, *args ):

    qjsValueArgs = [ a if isinstance( a, QJSValue ) else QJSValue( a )
                     for a in args ]
    if instance:
        return qjsValue.callWithInstance( instance, qjsValueArgs )
        return qjsValue.call( qjsValueArgs )

---------------------- >8 ----------------

On Mon, Jan 5, 2015 at 8:04 AM, Phil Thompson <phil at riverbankcomputing.com>

> On 03/01/2015 5:10 pm, B. B. wrote:
>> Hey Phil,
>> The error had actually been easier explained making a short example from
>> the beginning...
>> Attatched is the sources for a very small program that demostrate what I
>> mean.
>> The introspection is done just by printing to the console.
>> I print out in 2 sections - the first "makes sence" with the new source,
>> the second makes sence with the old sources.
>> You will notice in the second - with the old sources - the result from the
>> "getStuff" function is python dicts and lists.
>> Which if a much cleaner interface than the QJSValues the getStuff returns
>> with the nevest sources.. :-)
> It's a change in behaviour in Qt v5.4 - nothing to do with PyQt.
> I could implement the mapping protocol for QJSValue so that __getitem__
> calls property(), __setitem__ calls setProperty() and __delitem__ calls
> deleteProperty(). Would that help?
> Phil
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20150107/3f6bf37d/attachment-0001.html>

More information about the PyQt mailing list