• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Qt第十六章QWidget和QML混合开发

武飞扬头像
苍穹之跃
帮助1

目录

一、Qml作为窗口引入

二、Qml作为控件引入(Qml根组件不能是window)

三、两个问题①Qml文件如何调用python函数②python代码如何控制Qml元素。


一、Qml作为窗口引入

例:QWidget窗口中用按钮打开和关闭Qml窗口
①QWidget窗口

  1.  
    import sys
  2.  
    from pathlib import Path
  3.  
     
  4.  
    from PySide6.QtCore import QObject, Slot
  5.  
    from PySide6.QtQml import QQmlApplicationEngine
  6.  
    from PySide6.QtQuick import QQuickItem
  7.  
    from PySide6.QtWidgets import QApplication, QWidget, QPushButton
  8.  
     
  9.  
    class TestWidget(QWidget):
  10.  
    def __init__(self, parent=None):
  11.  
    super(TestWidget, self).__init__(parent)
  12.  
    self.button_open = QPushButton(self)
  13.  
    self.button_open.setText("打开Qml窗口")
  14.  
    self.button_open.setGeometry(0, 100, 100, 50)
  15.  
    self.button_open.clicked.connect(self.handle_button_open_click)
  16.  
    self.button_close = QPushButton(self)
  17.  
    self.button_close.setText("关闭Qml窗口")
  18.  
    self.button_close.setGeometry(100, 100, 100, 50)
  19.  
    self.button_close.clicked.connect(self.handle_button_close_click)
  20.  
     
  21.  
    # 打开Qml窗口
  22.  
    def handle_button_open_click(self):
  23.  
    self.widget = LoginQuickWidget()
  24.  
     
  25.  
    # 关闭Qml窗口
  26.  
    def handle_button_close_click(self):
  27.  
    if hasattr(self, 'widget') and self.widget:
  28.  
    del self.widget
  29.  
     
  30.  
     
  31.  
    if __name__ == '__main__':
  32.  
    app = QApplication([])
  33.  
    widget = TestWidget()
  34.  
    widget.show()
  35.  
    app.exec()

②Qml窗口

注意:此处是直接引入qml文件。如果是从qrc资源文件中引入qml,则直接QQmlApplicationEngine.load即可
学新通 学新通

  1.  
    # 槽函数类(一个承载槽函数的容器类)
  2.  
    class Slots(QObject):
  3.  
    def __init__(self, objects):
  4.  
    self.objects = objects
  5.  
    super().__init__()
  6.  
     
  7.  
    @Slot(str, result=None)
  8.  
    def set_text_msg(self, msg):
  9.  
    # 获取qml中的Text对象
  10.  
    child = self.objects[0].findChild(QQuickItem, "text1")
  11.  
    # 获取对象属性
  12.  
    p = child.property("text")
  13.  
    # 设置对象属性
  14.  
    child.setProperty("text", p msg)
  15.  
     
  16.  
    @Slot(result=str)
  17.  
    def get_text_msg(self):
  18.  
    return "皎氯"
  19.  
     
  20.  
     
  21.  
    """
  22.  
    这种方式是以Qml作为窗口来使用。所有的逻辑UI都由Qml来完成。python提供可以调用数据的API即可。
  23.  
    """
  24.  
     
  25.  
     
  26.  
    class LoginQuickWidget:
  27.  
    def __init__(self):
  28.  
    # 初始化UI
  29.  
    self.engine = QQmlApplicationEngine()
  30.  
    qml_file = Path(__file__).resolve().parent / "login.qml"
  31.  
    # 加载qml文件
  32.  
    self.engine.load(qml_file)
  33.  
    if not self.engine.rootObjects():
  34.  
    sys.exit(-1)
  35.  
    # qml对象集合
  36.  
    objects = self.engine.rootObjects()
  37.  
    # 实例化槽函数
  38.  
    self.slots = Slots(objects)
  39.  
    # 注入槽函数
  40.  
    self.engine.rootContext().setContextProperty('slots', self.slots)

③Qml文件

  1.  
    /**************************QML文件**************************/
  2.  
     
  3.  
    import QtQuick
  4.  
    import QtQuick.Window
  5.  
    import QtQuick.Controls 6.3
  6.  
    import QtQuick.Layouts 6.3
  7.  
    import QtQuick.Controls.Windows 6.0
  8.  
     
  9.  
    //主窗口
  10.  
    Window {
  11.  
    width: 800
  12.  
    height: 400
  13.  
    visible: true
  14.  
    title: qsTr("测试窗口")
  15.  
    Image {
  16.  
    id:background_image
  17.  
    anchors.fill: parent
  18.  
    fillMode: Image.PreserveAspectCrop
  19.  
    source: "http://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg"
  20.  
    antialiasing: true
  21.  
    }
  22.  
    //文本展示框
  23.  
    Text {
  24.  
    id: text1
  25.  
    //用于python获取此对象
  26.  
    objectName:"text1"
  27.  
    x: 300
  28.  
    y: 20
  29.  
    width: 200
  30.  
    height: 34
  31.  
    text: qsTr("初始值")
  32.  
    font.pixelSize: 12
  33.  
    }
  34.  
     
  35.  
    //一:通过JavaScript控制UI逻辑
  36.  
    Button {
  37.  
    id: button
  38.  
    x: 125
  39.  
    y: 179
  40.  
    width: 125
  41.  
    height: 29
  42.  
    text: qsTr("调用JavaScript方法")
  43.  
    //点击事件
  44.  
    onClicked: {
  45.  
    change()
  46.  
    }
  47.  
    //JavaScript函数
  48.  
    function change(){
  49.  
    var date = new Date();
  50.  
    text1.text=qsTr(date.getFullYear() "年" (date.getMonth() 1) "月" date.getDate() "日" date.getHours() "时" date.getMinutes() "分" date.getSeconds() "秒")
  51.  
    }
  52.  
    }
  53.  
     
  54.  
    //二:通过Python控制UI逻辑(不推荐,因为要做UI与业务逻辑分离;槽函数相当于于ajax请求来获取数据,而不是去控制UI本身)
  55.  
    Button {
  56.  
    id: button1
  57.  
    x: 325
  58.  
    y: 179
  59.  
    width: 125
  60.  
    height: 29
  61.  
    text: qsTr("调用Python设置属性")
  62.  
    //点击事件
  63.  
    onClicked: {
  64.  
    //调用注入的槽函数,使用槽函数改变视图
  65.  
    slots.set_text_msg("小小改变")
  66.  
    }
  67.  
    }
  68.  
     
  69.  
    //三:通过Python获取数据,JavaScript渲染UI(推荐方式)
  70.  
    Button {
  71.  
    id: button2
  72.  
    x: 525
  73.  
    y: 179
  74.  
    width: 125
  75.  
    height: 29
  76.  
    text: qsTr("调用Python获取数据")
  77.  
    //点击事件
  78.  
    onClicked: {
  79.  
    //调用注入的槽函数,使用槽函数获取数据
  80.  
    var msg=slots.get_text_msg()
  81.  
    //利用JS进行渲染
  82.  
    text1.text=qsTr(msg)
  83.  
    }
  84.  
    }
  85.  
     
  86.  
    }

二、Qml作为控件引入(Qml根组件不能是window)

  1.  
    from PySide6.QtCore import QUrl, Slot, QObject
  2.  
    from PySide6.QtQuick import QQuickItem
  3.  
    from PySide6.QtQuickWidgets import QQuickWidget
  4.  
    from PySide6.QtWidgets import QWidget, QApplication, QVBoxLayout, QPushButton
  5.  
     
  6.  
     
  7.  
    # 槽函数类(一个承载槽函数的容器类)
  8.  
    class Slots(QObject):
  9.  
    def __init__(self, obj):
  10.  
    super(Slots, self).__init__()
  11.  
    self.obj = obj
  12.  
     
  13.  
    @Slot(str, result=None)
  14.  
    def set_text_msg(self, msg):
  15.  
    # 获取qml中的Text对象
  16.  
    child = self.obj.findChild(QQuickItem, "text1")
  17.  
    # 获取对象属性
  18.  
    p = child.property("text")
  19.  
    # 设置对象属性
  20.  
    child.setProperty("text", p msg)
  21.  
     
  22.  
    @Slot(result=str)
  23.  
    def get_text_msg(self):
  24.  
    return "皎氯"
  25.  
     
  26.  
     
  27.  
    class TestQWidget(QWidget):
  28.  
     
  29.  
    def __init__(self, parent=None):
  30.  
    super(TestQWidget, self).__init__(parent)
  31.  
    self.resize(800, 300)
  32.  
    # 垂直布局
  33.  
    self.layout = QVBoxLayout(self)
  34.  
    # OK按钮
  35.  
    self.button = QPushButton("OK")
  36.  
    self.button.clicked.connect(lambda: print("OK"))
  37.  
    self.layout.addWidget(self.button)
  38.  
     
  39.  
    # QML控件
  40.  
    self.qml_widget = QQuickWidget()
  41.  
    # 设置缩放模式
  42.  
    self.qml_widget.setResizeMode(QQuickWidget.ResizeMode.SizeRootObjectToView)
  43.  
    # 向QML中传入数据(必须在setSource之前传入)
  44.  
    self.qml_widget.rootContext().setContextProperty("obj", '张良')
  45.  
    self.qml_widget.setSource(QUrl("test2.qml"))
  46.  
    # 获取QML中的对象(必须在setSource之后)
  47.  
    self.root_object: QQuickItem = self.qml_widget.rootObject()
  48.  
    # 实例化槽函数
  49.  
    self.slots = Slots(self.root_object)
  50.  
    # 注入槽函数
  51.  
    self.qml_widget.rootContext().setContextProperty('slots', self.slots)
  52.  
     
  53.  
    # 获取对象
  54.  
    child: QQuickItem = self.root_object.findChild(QQuickItem, "text1")
  55.  
    # 获取对象属性
  56.  
    print(child.property("text"))
  57.  
     
  58.  
    # 加入布局
  59.  
    self.layout.addWidget(self.qml_widget)
  60.  
     
  61.  
     
  62.  
    if __name__ == '__main__':
  63.  
    app = QApplication([])
  64.  
    widget = TestQWidget()
  65.  
    widget.show()
  66.  
    app.exec()
  1.  
    import QtQuick
  2.  
    import QtQuick.Window
  3.  
    import QtQuick.Controls 6.3
  4.  
    import QtQuick.Layouts 6.3
  5.  
    import QtQuick.Controls.Windows 6.0
  6.  
     
  7.  
     
  8.  
    Rectangle {
  9.  
    id:root
  10.  
    color: "yellow"
  11.  
    radius:10
  12.  
    //背景图
  13.  
    Image {
  14.  
    id:background_image
  15.  
    anchors.fill: parent
  16.  
    fillMode: Image.PreserveAspectCrop
  17.  
    source: "http://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg"
  18.  
    antialiasing: true
  19.  
    }
  20.  
    //文本展示框
  21.  
    Text {
  22.  
    id: text1
  23.  
    //用于python获取此对象
  24.  
    objectName:"text1"
  25.  
    x: 300
  26.  
    y: 20
  27.  
    width: 200
  28.  
    height: 34
  29.  
    text: qsTr(obj)
  30.  
    font.pixelSize: 12
  31.  
    }
  32.  
     
  33.  
    //一:通过JavaScript控制UI逻辑
  34.  
    Button {
  35.  
    id: button
  36.  
    x: 125
  37.  
    y: 179
  38.  
    width: 125
  39.  
    height: 29
  40.  
    text: qsTr("调用JavaScript方法")
  41.  
    //点击事件
  42.  
    onClicked: {
  43.  
    change()
  44.  
    }
  45.  
    //JavaScript函数
  46.  
    function change(){
  47.  
    var date = new Date();
  48.  
    text1.text=qsTr(date.getFullYear() "年" (date.getMonth() 1) "月" date.getDate() "日" date.getHours() "时" date.getMinutes() "分" date.getSeconds() "秒")
  49.  
    }
  50.  
    }
  51.  
     
  52.  
    //二:通过Python控制UI逻辑(不推荐,因为要做UI与业务逻辑分离;槽函数相当于于ajax请求来获取数据,而不是去控制UI本身)
  53.  
    Button {
  54.  
    id: button1
  55.  
    x: 325
  56.  
    y: 179
  57.  
    width: 125
  58.  
    height: 29
  59.  
    text: qsTr("调用Python设置属性")
  60.  
    //点击事件
  61.  
    onClicked: {
  62.  
    //调用注入的槽函数,使用槽函数改变视图
  63.  
    slots.set_text_msg("小小改变")
  64.  
    }
  65.  
    }
  66.  
     
  67.  
    //三:通过Python获取数据,JavaScript渲染UI(推荐方式)
  68.  
    Button {
  69.  
    id: button2
  70.  
    x: 525
  71.  
    y: 179
  72.  
    width: 125
  73.  
    height: 29
  74.  
    text: qsTr("调用Python获取数据")
  75.  
    //点击事件
  76.  
    onClicked: {
  77.  
    //调用注入的槽函数,使用槽函数获取数据
  78.  
    var msg=slots.get_text_msg()
  79.  
    //利用JS进行渲染
  80.  
    text1.text=qsTr(msg)
  81.  
    }
  82.  
    }
  83.  
     
  84.  
    }

三、3个问题①Qml文件如何调用python函数②python代码如何控制Qml元素。③python如何执行Qml中的函数。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbkckf
系列文章
更多 icon
同类精品
更多 icon
继续加载