QML 与 Python 交互

news2024/11/27 8:33:28

在 Qt 中,C++ 和 QML 交互一般有如下三种方法

  • 上下文属性:setContextProperty( )
  • 向引擎注册类型:调用 qmlRegisterType( )
  • QML 扩展插件:虽然有很大的灵活性,但是用 Python 创建 QML 插件比较麻烦,所以这种方法不适用于 Python

将 Python 代码暴露给 QML:上下文属性

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

class NumberGenerator(QObject):
    def __init__(self):
        QObject.__init__(self)

    nextNumber = Signal(int, arguments=['number'])


    @Slot()
    def giveNumber(self):
        self.nextNumber.emit(random.randint(0, 99))

if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    number_generator = NumberGenerator()
    engine.rootContext().setContextProperty('numberGenerator', number_generator)

    engine.load(QUrl("main.qml"))

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

import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.14

Window {
    id: root 
    width: 640
    height: 480
    visible: true 
    title: qsTr("Hello World")

    Flow {
        Button {
            text: qsTr("Give me a number")
            onClicked: numberGenerator.giveNumber()
        }
        Label {
            id: numberLabel
            text: qsTr("no number")
        }
    }
    Connections {
        target:numberGenerator
        function onNextNumber(number) {
            numberLabel.text = number
        }
    }

}

上述代码要结合 .py 文件进行理解,onClicked(发射 clicked 信号)会触发槽函数 numberGenerator.giveNumber(),该函数会发射 numberGenerator.nextNumber 信号,这个信号又被 QML 中的 onNextNumber 捕获,并修改 label 的显示结果。

.py 文件使用 setContextProperty() 函数 把 Python 对象 number_generator 暴露给 QML (对应 QML 中的 numberGenerator),这种方式会直接添加到 QML 的上下文环境中,在QML 中可以直接使用,不需要重新导入,使用方便,但容易导致命名冲突。

这里使用 Slot 装饰符将 giveNumber() 变成槽函数,不然无法使用

将 Python 对象暴露给 QML :注册类型

// #region global
import QtQuick
import QtQuick.Window
import QtQuick.Controls

import Generators

Window {
    id: root
  
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello Python World!")
  
    Flow {
        Button {
            text: qsTr("Give me a number!")
            onClicked: numberGenerator.giveNumber()
        }
        Label {
            id: numberLabel
            text: qsTr("no number")
        }
    }
  
    NumberGenerator {
        id: numberGenerator
    }

    Connections {
        target: numberGenerator
        function onNextNumber(number) {
            numberLabel.text = number
        }
    }
}
// #endregion global
#region global
import random
import sys

from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine, qmlRegisterType
from PySide6.QtCore import QUrl, QObject, Signal, Slot

class NumberGenerator(QObject):
    def __init__(self):
        QObject.__init__(self)
  
    nextNumber = Signal(int, arguments=['number'])

    @Slot()
    def giveNumber(self):
        self.nextNumber.emit(random.randint(0, 99))


if __name__ == '__main__':
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
  
    qmlRegisterType(NumberGenerator, 'Generators', 1, 0, 'NumberGenerator')
  
    # engine.load(QUrl("main.qml"))
    import os
    path = os.path.dirname(__file__) + os.sep + 'main.qml'
    engine.load(path)

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

main.qml 文件中需要导入 Python 注册的模块 Generators,并将类实例化为 NumberGenerator{…},该实例就可以向任何其他 QML 元素一样工作。

qmlRegisterType( ) 函数

把 Python 对象暴露给 QML ,主要使用 qmlRegisterType() 函数。qmlRegisterType( ) 函数来自于 PySide6.QtQml 模块并接收5个参数:

qmlRegisterType (pytype: type, uri: str, versionMajor: int, versionMinor: int, qmlName: str**)**

参数:

  • pytype (type) – Python 类(py文件中的类名)
  • uri (str) – 表示对类的引用,如本案例的 Generator(QML中 import 的名称)
  • versionMajor (int) – 主要版本编号,如本案例中的 1
  • versionMinor (int) – 次要版本编号,如本案例中的 0
  • qmlName (str) – 暴露给QML的类名称,本案例中的 NumberGenerator

返回类型:int (the QML type id)

相互关系如下图所示:
在这里插入图片描述

在 QML 中调用 Python 属性的方法

这是一种常用的方法,先介绍 Python 中的 Property( ) 函数——property() 函数的作用是在新式类中返回属性值。

class property([fget[, fset[, fdel[, doc]]]])

参数

  • fget – 获取属性值的函数
  • fset – 设置属性值的函数
  • fdel – 删除属性值函数
  • doc – 属性描述信息

返回值: 返回新式类属性。

举例如下:

class C (object):
    def __init__(self):
        self._x = None

    def getx(self):
        return self._x
  
    def setx(self, value):
        self._x = value

    def delx(self):
        del self._x

    x = property(getx, setx, delx, "I am the 'x' property.")

如果 c = C( ),则 c.x 将触发 getter 信号, c.x = value 将触发 setter 信号,del c.x 将触发 deleter 信号。

参照 Python 中的 Property( ) 函数,Qt 中不仅提供了自己的属性,还提供了信号和槽的支持。由此可以理解,以下代码的几个参数分别表示类型,已及 getter 信号、setter 信号和通知信号(当属性改变时需要发出该信号,通知属性的变化):

from PySide6.QtCore import Property
maxNumber = Property(int, get_max_number, set_max_number, notify = maxNumberChanged)

之所以绕一圈进行修改,是因为在 QML 中直接通过 JavaScript 更改属性会破坏与属性的绑定,而通过显示使用 setter( ) 函数可以避免这种情况。

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/651021.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【补充:CAN卡通信的下位机-STM32cubeIDE-hal库+STMF1xx+数据发送和接收+中断接收方式+基础样例3】

【CAN卡通信的下位机-STM32cubeIDE-hal库STMF4xx数据发送和接收中断接收方式基础样例3】 1、概述2、实验环境3、问题描述4、大佬指点与解决问题5、实验效果截图6、代码连接7、细节部分8、总结 ) 1、概述 从第一篇F1和F4上采用轮询的方式调试can, 【CAN卡通信的下位…

如何用Jmeter进行接口测试 ,这应该是全网最详细的教程了

一、Jmeter 的使用步骤 打开Jmeter 安装包,进入\bin 中,找到"jmeter.bat", 点击打开即可。 在下图打开的Jmeter 页面中,右键“测试计划” -> “添加” -> "Threads(Users)" -> “线程组”, 建立线…

Allure安装、使用、Jenkins集成

目录 一、allure介绍 二、安装allure服务 三、安装pytest、allure-pytest 插件 四、生成报告 五、allure其他使用 5.1 给测试报告添加各种附件 5.2 添加用例标题和描述信息 5.3 添加链接 5.4 标记测试用例 5.5 优先级 六、allure和jenkins集成 一、allure介绍 all…

2023年5月青少年软件编程(图形化) 等级考试试卷(三级)

青少年软件编程(图形化) 等级考试试卷(三级) 一、 单选题(共 25 题, 共 50 分) 1.关于变量, 下列描述错误的是? ( ) A.只能建一个变量 B.变量可以隐藏 C.变量可以删除 D.…

【抽样调查】实验

文章目录 1、数组矩阵简单抽样(1)构造数组(2)构造矩阵(3)产生来自正态分布的随机数(4)从正态总体中抽取若干个样本(5)对矩阵的行或列进行统计计算 2、R软件作…

输入信号、冲激响应与卷积

输入信号与冲激响应的离散卷积 系统冲激响应: h ( t ) ∑ τ 0 ∞ x ( t ) δ ( t − τ ) h(t)\sum_{\tau0}^{\infty}x(t)\delta(t-\tau ) h(t)τ0∑∞​x(t)δ(t−τ) 上式中 h ( t ) h(t) h(t)是冲激信号输入到系统后系统的输出,也是系统对外在激…

stl容器vector笔记

Vector 一、初始化二、常用方法1. 访问元素at()、下标、data()、front()、back()2. push_back()、pop_back()尾部增删元素3. insert()在pos前插入元素,返回插入位置4. erase()擦除元素,返回擦除元素后的元素位置5. clear()清空容器6. resize()改变容器元…

C语言中函数返回数组(一维和二维)

文章目录 函数返回一维数组函数返回二维数组 C语言中函数返回数组是很重要的一种应用,有时候在程序中调用函数返回数组可以更容易的实现我们想要的某些操作,比如一次返回多个值,这篇文章带来的是C语言中函数返回一维数组和二维数组的例子。 函…

Python自动化测试框架我到底应该学哪一个?

企业中,自动化必定会演变成搭建测试框架,这是为什么呢? 可能有一些刚刚进入软件测试行业的朋友还不理解什么是测试框架,没关系,首先我们知道一点,为什么自动化会演变成搭建测试框架呢? 第一个…

Ribbon和 Nacos服务注册中心

✅作者简介:大家好,我是Cisyam,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Cisyam-Shark的博客 💞当前专栏: 微服务探索之旅 ✨特色专…

软件测试面试自己都不上心,就不要抱怨别人对你冷眼旁观

昨日表哥恳请帮他的学生投递一下开发岗的简历,举手之劳,这忙必须得帮。但当发来学生的简历后,我吐槽了“这简历平平无奇,没有任何亮点,如何令人另眼相看?”表哥说,学生经历不多,总不…

离散数学题目收集整理练习(期末过关进度20%)

✨博主:命运之光 🦄专栏:离散数学考前复习(知识点题) 🍓专栏:概率论期末速成(一套卷) 🐳专栏:数字电路考前复习 ✨博主的其他文章:点击…

一文看懂什么是广告联盟,未来可期吗?

日常学习一些行业内的相关基础知识,可以在工作中更好地理解业务。在互联网广告行业中,广告联盟是很重要的存在,我们今天一起来了解下什么是广告联盟吧。 文中GG联盟广告联盟 GG广告 一. 定义 GG联盟通指网络GG联盟,指集合中小网…

【链表复习】C++ 链表复习及题目解析 (3)

目录 剑指offer 中的链表题目 JZ6 从尾到头打印链表 JZ18 删除链表的结点 JZ24 反转链表 JZ25 合并两个排序的链表 JZ52 两个链表的第一个公共结点 JZ23 链表中环的入口结点 JZ22 链表中倒数第k 个结点 JZ35 复杂链表的复制 JZ76 删除链表中重复的结点 本次给大家带来…

用注解实现方法开关

一、自定义注解的基本使用 java.lang.annotation 提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解): Documented – 注解是否将包含在JavaDoc中 Retention – 什么时候使用该注解 Target –…

【算法】动态规划-斐波那契模型

文章目录 结论斐波那契模型第 N 个泰波那契数三步问题使用最小花费爬楼梯**方法1:**以i位置为结尾....方法2:以i位置为起点.... 解码方法 结论 对于线性dp,一般是用经验题目要求来定义状态表示: 以某个位置为结尾…以某个位置为…

React 通过一个输入内容加入列表案例熟悉 Hook 基本使用

我们创建一个react项目 在src下创建components文件夹 在下面创建一个index.jsx index.jsx 参考代码如下 import React, { useState } from "react";const useInputValue (initialValue) > {const [value,setValue] useState(initialValue);return {value,onCha…

【2023,学点儿新Java-01】从查看本机 jdk版本 开始 | Java基础全程脉络图、Java工程师全程技术路线、Java职业晋升路线图

一个人把生命耗尽,应该是为了一些美好的东西,值得的东西,用蓬勃如烈火的生命力 去战胜一个又一个人生的悲剧,这本身就是人生的意义之一吧! 🎯作者主页: 追光者♂🔥 🌸个人…

Win10 系统专业版远程桌面如何才能多用户同时登录使用?

环境: Win10专业版19041 RDPWrap-v1.6.2 dell5493笔记本 问题描述: Win10 系统专业版远程桌面如何才能多用户同时登录使用? 解决方案: 安装RDPWrap 1.关闭remote desktop services服务 安装RDP之前,要先关闭re…

8年性能测试工程师告诉你,压力测试详解,如何做压力测试...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 什么是压力测试&a…