导言


在这里插入图片描述
这张图展示的是 QML 与 Python 双向交互,也就是 调用 Python 方法并返回结果给 QML。QML → Python(传入参数) → Python 处理 → 返回结果给 QML 的完整闭环。

效果如下所示:
在这里插入图片描述
工程代码:

  • github: https://github.com/q164129345/myPyside6_QML/tree/main/basic04_button_slot_para_return
  • gitee: https://gitee.com/wallace89/myPyside6_QML/tree/main/basic04_button_slot_para_return

一、main.py


import sys
from PySide6.QtCore import QObject, Slot
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine

class Backend(QObject):
    @Slot(str, result=str)  # 装饰器,声明这是一个槽函数,接受一个字符串参数,返回一个字符串
    def greet(self, name: str) -> str:
        return f"Hello, {name} from Python!"

if __name__ == "__main__":
    # 创建应用程序和引擎
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    # qml与python交互
    backend = Backend() # 实例化python后端对象
    engine.rootContext().setContextProperty("backend", backend) # 注册到QML环境(名叫 “backend”)

    # 加载QML文件
    engine.addImportPath(sys.path[0])  # 当前项目路径
    engine.loadFromModule("Example", "Main")  # 模块(Example) + QML文件名(Main.qml)

    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec())

关键点说明

class Backend(QObject):
    @Slot(str, result=str)  # 装饰器,声明这是一个槽函数,接受一个字符串参数,返回一个字符串
    def greet(self, name: str) -> str:
        return f"Hello, {name} from Python!"
  • 继承 QObject:让这个类能够作为 Qt 的对象被 QML 识别和调用。
  • @Slot(str, result=str)
      • 告诉 Qt 这是一个槽函数,QML 可以直接调用它。
    • (str, result=str) 指定参数类型为字符串。这样 QML 在调用时必须传入字符串。并指令返回类型为字符串。

二、Main.qml


// 导入QML基础模块,包含基本的QML元素
import QtQuick 2.15
// 导入Qt控件模块,包含Button等界面控件
import QtQuick.Controls 2.15

// 应用程序主窗口
ApplicationWindow {
    visible: true         // 窗口可见
    width: 400            // 窗口宽度为400像素
    height: 300           // 窗口高度为300像素
    title: qsTr("QML 调用 Python 返回值")  // 窗口标题,qsTr用于国际化

    // Column布局:垂直排列子元素
    Column {
        anchors.centerIn: parent  // 将Column布局锚定到父元素(窗口)的中心
        spacing: 20              // 子元素之间的垂直间距为20像素

        // 文本输入框:用于输入用户名字
        TextField {
            id: inputName                    // 给输入框设置唯一标识符,便于引用
            placeholderText: "输入名字"      // 当输入框为空时显示的提示文本
            width: 200                      // 输入框宽度为200像素
        }

        // 按钮:点击后调用Python函数并显示返回值
        Button {
            text: "点我问候"                 // 按钮显示的文本
            onClicked: {                    // 点击事件处理器
                // 调用 Python 后端的方法,传入输入框的文本作为参数
                // backend.greet() 返回一个字符串消息
                let msg = backend.greet(inputName.text)
                // 将返回的消息设置到输出标签的文本中
                outputLabel.text = msg
            }
        }

        // 标签:用于显示Python函数返回的结果
        Label {
            id: outputLabel                // 给标签设置唯一标识符,便于引用
            text: "等待点击按钮..."         // 初始显示的文本
        }
    }
}

关键点说明

// 文本输入框:用于输入用户名字
TextField {
	id: inputName                    // 给输入框设置唯一标识符,便于引用
	placeholderText: "输入名字"      // 当输入框为空时显示的提示文本
	width: 200                      // 输入框宽度为200像素
}

// 按钮:点击后调用Python函数并显示返回值
Button {
	text: "点我问候"                 // 按钮显示的文本
	onClicked: {                    // 点击事件处理器
		// 调用 Python 后端的方法,传入输入框的文本作为参数
		// backend.greet() 返回一个字符串消息
		let msg = backend.greet(inputName.text)
		// 将返回的消息设置到输出标签的文本中
		outputLabel.text = msg
	}
}

// 标签:用于显示Python函数返回的结果
Label {
	id: outputLabel                // 给标签设置唯一标识符,便于引用
	text: "等待点击按钮..."         // 初始显示的文本
}

  • 输入框:让用户输入名字(字符串)
  • 按钮:触发事件,运行Python代码backend.greet(inputName.text),将输入框的字符串作为入口参数。
  • 标签:显示Python代码返回的结果(更新界面)。

三、细节补充


3.1、QML中变量声明的类型

在QML的JavaScript代码块中,您可以使用以下三种方式声明变量:

  1. let - 块级作用域变量(推荐使用)
    • 只能在声明的代码块内访问
    • 可以重新赋值
    • 代码中 let msg = backend.greet(inputName.text) 就是这种用法
  2. const - 块级作用域常量
    • 声明后不能重新赋值
    • 同样是块级作用域
  3. var - 函数级作用域变量(较旧的语法)
    • 在整个函数内都有效
    • 不推荐在新代码中使用

变量类型特点
QML中的变量是动态类型的,类型由赋值的内容决定:

  • let msg = "hello" → 字符串类型
  • let count = 42 → 数字类型
  • let data = {name: "John"} → 对象类型
  • let list = [1, 2, 3] → 数组类型
    代码中,let msg 接收的是Python函数返回的字符串,所以它是字符串类型。

更多推荐