Search code examples
pythonqmlpyside2

How to convert a python list to a QVariantList in PySide2


So, PySide2 has removed the QVariant* types.

However, QtQuick expose a great deal of QVariant API.

More specifically, i want to use the very handy feature to pass a QVariantList as a model of ListView without having to implement a fully blown QAIM.

However, by feeding such an object to QML via setContextProperty

class Test(QObject):
   def __init__(self):

       super(Test, self).__init__()
       self.propertyList = ["FOO", "BAR", 1]

   def model(self):
       return self.propertyList

   modelChanged = Signal()
   model = Property(list, model, notify=modelChanged)

And then printing .model yields:

qml: QVariant(PySide::PyObjectWrapper)

So how to pass a python list to qml in a form that is actually understood by qml?


Solution

  • You have to pass as type of Property to "QVariantList":

    from PySide2 import QtCore, QtGui, QtQml
    
    
    class Test(QtCore.QObject):
        modelChanged = QtCore.Signal()
    
        def __init__(self, parent=None):
            super(Test, self).__init__(parent)
            self.propertyList = ["FOO", "BAR", 1]
    
        def model(self):
            return self.propertyList
    
        model = QtCore.Property("QVariantList", fget=model, notify=modelChanged)
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtGui.QGuiApplication(sys.argv)
    
        pyobject = Test()
    
        engine = QtQml.QQmlApplicationEngine()
        ctx = engine.rootContext()
        ctx.setContextProperty("pyobject", pyobject)
        engine.load(QtCore.QUrl.fromLocalFile("main.qml"))
        engine.quit.connect(app.quit)
    
        sys.exit(app.exec_())
    
    import QtQuick 2.12
    import QtQuick.Window 2.12
    
    Window{
        visible: true
        width: 640
        height: 480
    
        Component.onCompleted: console.log(pyobject.model)
    }
    

    Output:

    qml: [FOO,BAR,1]
    

    Note: In the case of PyQt5 list native of python is converted directly to the list of QML, unlike PySide2 you must indicate the types of Qt and if they do not exist directly as types you must indicate it as string.