前言
在 PySide2 中,Python和QML之间的交互主要使用信号与槽机制。
QML调用Python
以下是一个简单的步骤说明:
方法的类
创建一个 QObject 子类
首先,你需要创建一个继承自 QObject
的 Python 类,并在类中定义你希望在 QML 中调用的方法。
使用 @Slot
装饰器来标记这些方法,以便它们可以在 QML 中被调用。
1 | from PySide2.QtCore import QObject, Slot |
注意下面的写法是不行的
1 |
|
这是因为在 PyQt 或 PySide 中,槽函数的返回类型声明需要使用 Python 的内置类型(如 list
),而不是类型注解(如 List[str]
)。List[str]
是 typing
模块中的类型,而 PyQt 或 PySide 的槽机制不直接支持 typing
模块的类型声明。
改成这样也是可以的
1 |
|
暴露实例
将 Python 对象暴露给 QML
接下来,你需要将这个 Python 对象暴露给 QML。
你可以通过 QQuickView
或 QQmlApplicationEngine
来加载 QML 文件,并将 Python 对象设置为 QML 上下文中的属性。
1 | from PySide2.QtGui import QGuiApplication |
注意
一定要在加载页面前设置属性,否则在
Component.onCompleted
生命周期中获取不到。
例如
1 | Component.onCompleted: { |
QML中调用
在 QML 中调用 Python 方法
在 QML 文件中,你可以通过 qmlObject
来访问 myMethod
方法。
1 | import QtQuick 2.12 |
总结
- 创建一个继承自
QObject
的 Python 类,并使用@Slot
装饰器标记你希望在 QML 中调用的方法。 - 将这个 Python 对象通过
setContextProperty
方法暴露给 QML。 - 在 QML 中通过对象名调用 Python 方法。
这样,你就可以在 QML 中调用 Python 方法了。
Python调用QML方法
准确来说这个不是Python直接调用QML的方法,而是通过QML监听Python的信号来使用同样的目的。
数据的类
1 | from PySide2.QtCore import Property, QObject, Signal, Slot |
也就是定义信号和发送信号
1 | # 定义信号 |
其中
@Property(int)
是为了在QML中能取值@Slot(str)
是为了在QML中能调用方法
多个参数的信号
1 | showToast = Signal(str, int) |
注意:
信号在QML中用
on+信号名(首字母大写)
进行监听。
暴露实例
1 | # 创建 QmlCommon 的实例 |
QML中监听
1 | Connections { |
监听到但是无法更新
如果我们监听到事件了,在事件中更新UI,但是不生效,是因为接受信号时,UI还没渲染完毕。
我们可以这样处理
1 | from PySide2.QtCore import QUrl, QTimer |
注意
QML的创建完毕事件中,UI也没有渲染完毕,这里使用的延迟发送信号。
当然我们再调用接口后更新的时候UI基本都渲染完毕了。
QML绑定Python中的属性
使用Q_PROPERTY
定义数据类
1 | from PySide2.QtCore import Property, QObject, Signal |
这里属性和信号绑定,一旦收到变化信号,绑定这个属性的就会自动更新。
跟上面的区别在于,不用监听事件自己处理了。
暴露实例
1 | # 创建实例 |
QML中使用
1 | Button { |