QML 与 Python 交互

这篇具有很好参考价值的文章主要介绍了QML 与 Python 交互。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在 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 交互

在 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( ) 函数可以避免这种情况。

参考


QML 与 Python 交互文章来源地址https://www.toymoban.com/news/detail-486991.html

到了这里,关于QML 与 Python 交互的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python函数-上下文管理器

    上下文管理协议(Context Management Protocol):包含方法 enter () 和 exit (),支持该协议的对象要实现这两个方法。 上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了__enter__() 和 exit () 方法。 上下文管理器定义执行 with 语句时要建立的运行时上下文,负

    2024年02月12日
    浏览(37)
  • java: 无法从静态上下文中引用非静态 方法

    Java中静态上下文中无法引用非静态变量的解决办法: 一、为什么不能引用? 今天编写代码遇到 non-static variable mainframe cannot be referenced from a static context  经过了解知道了因为静态类的方法可以在没有创建实例对象时直接调用,而非静态的成员变量是一个对象属性,只有在对象

    2024年02月08日
    浏览(30)
  • python 上下文管理器 with 语句

    上下文管理器 with 语句可以自动地分配和释放资源。 这篇文章中介绍了文件读写的方法,每次读取文件时要使用 open() 函数打开文件,使用结束后要用 close() 函数关闭文件。有时,我们会忘记关闭文件,或者打开了许多文件占用太多资源。使用上下文管理器 with 语句可以方便

    2023年04月09日
    浏览(47)
  • Python教程(27)——如何使用Python中的上下文管理器

    当我们在编写代码时,经常会遇到需要管理资源的情况,比如打开和关闭文件,如果遇到了一些异常情况,我们需要关闭资源,不然会导致资源泄露,虽然我们可以通过手动的方式来关闭,但如果有多个异常情况需要考虑的话,万一不小心漏了一处,就芭比Q了。所以,如果有

    2024年02月19日
    浏览(40)
  • Python高级语法:with语句和上下文管理器

    1.文件操作说明: ①文件使用完后必须关闭。 ②因文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的。 例如:  2. 存在的安全隐患: ① 由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。 例如: 运行结果: 3.try…except…

    2024年02月04日
    浏览(46)
  • 【 Python 全栈开发 - WEB开发篇 - 38 】property和上下文管理器

    Python 是一个简洁而强大的编程语言,通过提供各种特性和工具,使开发人员能够更高效地进行编程。其中一个非常有用的特性是 @property 装饰器,它允许我们在类中定义属性并自定义其行为。 @property 装饰器用于将一个方法转换为类的属性。使用 @property 装饰器,我们可以像访

    2024年02月13日
    浏览(47)
  • LLMs之llama_7b_qlora:源代码解读inference_qlora.py(模型推理)使用LORA权重来初始化预训练的LLAMA模型来进行文本生成(基于用户交互输入的上下文生成新文本)

    LLMs之llama_7b_qlora:源码解读inference_qlora.py(模型推理)使用LORA权重来初始化预训练的LLAMA模型来进行文本生成(基于用户交互输入的上下文生成新文本) 目录

    2024年02月15日
    浏览(55)
  • QML 与 Python 交互

    在 Qt 中,C++ 和 QML 交互一般有如下三种方法 上下文属性:setContextProperty( ) 向引擎注册类型:调用 qmlRegisterType( ) QML 扩展插件:虽然有很大的灵活性,但是用 Python 创建 QML 插件比较麻烦,所以这种方法不适用于 Python 上述代码要结合 .py 文件进行理解,onClicked(发射 clicked 信

    2024年02月09日
    浏览(32)
  • 无限上下文,多级内存管理!突破ChatGPT等大语言模型上下文限制

    目前,ChatGPT、Llama 2、文心一言等主流大语言模型,因技术架构的问题上下文输入一直受到限制,即便是Claude 最多只支持10万token输入,这对于解读上百页报告、书籍、论文来说非常不方便。 为了解决这一难题,加州伯克利分校受操作系统的内存管理机制启发,提出了MemGPT。

    2024年02月06日
    浏览(47)
  • 从零开始理解Linux中断架构(7)--- Linux执行上下文之中断上下文

            当前运行的loop是一条执行流,中断程序运行开启了另外一条执行流,从上一节得知这是三种跳转的第三类,这个是一个大跳转。对中断程序的基本要求就是 中断执行完毕后要恢复到原来执行的程序 ,除了时间流逝外,原来运行的程序应该毫无感知。        

    2024年02月11日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包