如何在 QML 中创建 PyQT 注册类型的动态实例

Posted

技术标签:

【中文标题】如何在 QML 中创建 PyQT 注册类型的动态实例【英文标题】:How to create dynamic instances of PyQT registered types in QML 【发布时间】:2020-11-01 22:50:36 【问题描述】:

Registering Python Types 为基础:https://www.riverbankcomputing.com/static/Docs/PyQt5/qml.html 我希望能够在 QML 中动态实例化已注册 Python 类型的实例。

例如定义人员类型:

class Person(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)

        self._name = ''

    @pyqtProperty('QString')
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name

# ...
qmlRegisterType(Person, 'People', 1, 0, 'Person')

现在在 QML 中,我想说在单击按钮时创建一个新的 Person 对象,例如:

import People 1.0

import QtQuick 2.7
import QtQuick.Layouts 1.12
import QtQuick.Window 2.2
import QtQuick.Controls 2.5

// create application window etc.
// add a button
Button 
    text: "Ok"
    onClicked: 
        var p = new Person();
        p.name = 'Bob';
    

这不起作用。我认为 Qt 的 createComponent 函数可能是可行的方法,但我无法让它工作。

【问题讨论】:

【参考方案1】:

如果你想通过以下方式创建组件来动态实例化qml对象:

function create_person(name)
    var p = Qt.createQmlObject("import People 1.0; Person", null, "createPerson")
    p.name = name

Button 
    text: "Ok"
    onClicked: var p = create_person("Bob")

或者

Component 
    id: person_provider
    Person
    

function create_person(name)
    var p = person_provider(null)
    p.name = name

Button 
    text: "Ok"
    onClicked: var p = create_person("Bob")

【讨论】:

【参考方案2】:

您正在尝试将其实例化,就好像它是一个 javascript 对象一样。但事实并非如此。您创建了一个 QML 对象。所以你必须以这种方式实例化它,如下所示:

import People 1.0
import QtQuick 2.7

Person 
    name: 'Bob'

如果您想动态创建它,那么您也可以使用 QML 方式:

function createPerson() 
    var qml = "import QtQuick 2.0; import People 1.0; Person  name: 'Bob' ";
    var personObj = Qt.createQmlObject(qml, parentObj, "createPerson");

【讨论】:

以上是关于如何在 QML 中创建 PyQT 注册类型的动态实例的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QML 中创建动态委托?

在 QML 中创建自定义 C++ 对象并将其存储在 C++ 模型中

在 PyQt 中创建动态按钮

如何在 python 中创建路径并将其显示在 qml 画布上

不能在 QML 中创建地图数据类型吗?

如何在 QML 中创建延迟函数?