08. 自定义组件

一、在单独文件中自定义组件

  我们可以在终端中使用 pip 安装 PySide6 模块。默认是从国外的主站上下载,因此,我们可能会遇到网络不好的情况导致下载失败。我们可以在 pip 指令后通过 -i 指定国内镜像源下载

pip install pyside6 -i https://mirrors.aliyun.com/pypi/simple

  国内常用的 pip 下载源列表:

  • 阿里云 https://mirrors.aliyun.com/pypi/simple
  • 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple
  • 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple
  • 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple

  虽然 QML 中提供了多个样式可供使用,但是用户有时还是想实现自定义的外观。这里,我们新建一个 MyButton.qml 文件,用来存放自定义的组件。

import QtQuickRectangle {id: containerRectIdwidth: buttonTextId.implicitWidth + 60height: buttonTextId.implicitHeight + 20color: "#99CCFF"// 为内部的Text元素提供一个别名属性,方便在外部设置按钮的文本property alias buttonText: buttonTextId.textsignal buttonClicked()                                                      // 自定义一个信号border {width: 1color: "#666666"}Text {id: buttonTextIdanchors.centerIn: parenttext: "按钮"font.pointSize: 16color: "#FF6666"}MouseArea {id: mouseAreaIdanchors.fill: parentonClicked: {containerRectId.buttonClicked()                                     // 触发信号}}
}

  在 QML 中,我们无法使用自定义组件内部元素的属性,因此,我们需要使用 alias 关键字给内部元素的属性起一个别名,方便在外部设置该内部元素的属性值。

  我们新建一个 template.qml 文件,在该文件中调用自定义的 QML 组件。

import QtQuick.Window
import QtQuick.Layouts// Window控件表示一个顶级窗口
// 在QML中,元素是通过大括号{}内的属性来配置的。
Window {width: 800                                                                  // 窗口的宽度height: 600                                                                 // 窗口的高度visible: true                                                               // 显示窗口color: "lightgray"                                                          // 窗口的背景颜色Text {id: textIdanchors.centerIn: parentfont.pointSize: 32color: "#FF6666"}Column {MyButton {buttonText: "按钮1"onButtonClicked: {textId.text = "按钮1被点击了"}}MyButton {buttonText: "按钮2"onButtonClicked: {textId.text = "按钮2被点击了"}}}
}

  这里,我们将 template.qml 文件和 MyButton.qml 文件放置到同一级目录下。然后,我们可以在 template.qml 文件中直接用存放自定义组件的文件名创建自定义组件。

  自定义组件的名称一定要与存放自定义组件的文件名首字母一致,否则会报如下错误:

file:///E:/Software/Python/PySide6/Template/template.qml:13:9: MyButton is not a type
file:///E:/Software/Python/PySide6/Template/template.qml: File name case mismatch   

  自定义组件的存放文件的首字母一定要大写,否则会报如下错误:

file:///E:/Software/Python/PySide6/Template/template.qml:22:9: Cannot assign to non-existent property "myButton"

  我们新建一个 template.py 文件,用来加载 template.qml 文件。

import sysfrom PySide6.QtWidgets import QApplication
from PySide6.QtQml import QQmlApplicationEngineif __name__ == "__main__":app = QApplication(sys.argv)                                                # 1.创建一个QApplication类的实例engine = QQmlApplicationEngine()                                            # 2.创建QML引擎对象engine.load("template.qml")                                                 # 3.加载QML文件sys.exit(app.exec())                                                        # 4.进入程序的主循环并通过exit()函数确保主循环安全结束

这里自定义组件的 QML 文件名的首字母一定要大写。

自定义的组件名与 QML 文件名一致。

组件实例的 id 和组成组件的顶层 Itemid 是各自独立的。

二、使用component自定义组件

  我们修改 template.qml 文件的内容,使用 component 自定义一个组件。

import QtQuick.Window// Window控件表示一个顶级窗口
// 在QML中,元素是通过大括号{}内的属性来配置的。
Window {width: 800                                                                  // 窗口的宽度height: 600                                                                 // 窗口的高度visible: true                                                               // 显示窗口color: "lightgray"// MyButton为自定义的组件名component MyButton: Rectangle {id: containerRectIdwidth: buttonTextId.implicitWidth + 60height: buttonTextId.implicitHeight + 20color: "#99CCFF"// 为内部的Text元素提供一个别名属性,方便在外部设置按钮的文本property alias buttonText: buttonTextId.textsignal buttonClicked()                                                  // 自定义一个信号border {color: "#666666"width: 1}Text {id: buttonTextIdtext: "按钮"font.pointSize: 16color: "#FF6666"anchors.centerIn: parent}MouseArea {id: mouseAreaIdanchors.fill: parentonClicked: {containerRectId.buttonClicked()                                 // 触发信号}}}Text {id: textIdanchors.centerIn: parentfont.pointSize: 32color: "#FF6666"}Row {spacing: 20MyButton {buttonText: "按钮1"onButtonClicked: {textId.text = "按钮1被点击了"}}MyButton {buttonText: "按钮2"onButtonClicked: {textId.text = "按钮2被点击了"}}}
}

三、Component组件

  Component 是由 Qt 框架或开发者封装好的、只暴露了必要接口的 QML 类型,可以重复利用。一个 QML 组件就像一个黑盒子,它通过属性、信号、函数和外部世界交互。

  Component 有两个信号:completed() 信号会在 对象实例化后 发出的信号,destruction() 信号会在 在对象开始销毁 时发出x信号。

  修改 template.qml 文件的内容。

import QtQuick.Window// Window控件表示一个顶级窗口
// 在QML中,元素是通过大括号{}内的属性来配置的。
Window {width: 800                                                                  // 窗口的宽度height: 600                                                                 // 窗口的高度visible: true                                                               // 显示窗口color: "lightgray"// 对象实例化后发出的信号。一旦建立了完整的 QML 环境,它就可用于在启动时执行脚本代码。Component.onCompleted: {console.log("Component.onCompleted")console.log("width: " + width, ", height: " + height, ", color: " + color)}// 在对象开始销毁时发出信号Component.onDestruction: {console.log("Component.onDestruction")}
}

  我们还可以自定义一个 ComponentComponent 只能包含一个顶层 Item,而且在这个顶层 Item 之外不能定义除了 id 属性以外的任何数据。而在顶层 Item 之内,则可以包含更多的子元素来协同工作,最终形成一个具有特定功能的组件。

import QtQuick.Window// Window控件表示一个顶级窗口
// 在QML中,元素是通过大括号{}内的属性来配置的。
Window {width: 800                                                                  // 窗口的宽度height: 600                                                                 // 窗口的高度visible: true                                                               // 显示窗口color: "lightgray"// 自定义一个Componoent,需要手动加载才会显示Component {// Component不能定义除id以外的其它属性id: buttonComponent// Component只能有一个顶层ItemRectangle {id: containerRectIdwidth: buttonTextId.implicitWidth + 60height: buttonTextId.implicitHeight + 20color: "#99CCFF"// 为内部的Text元素提供一个别名属性,方便在外部设置按钮的文本property alias buttonText: buttonTextId.textsignal buttonClicked()                                              // 自定义一个信号border {width: 1color: "#666666"}Text {id: buttonTextIdanchors.centerIn: parenttext: "按钮"font.pointSize: 16color: "#FF6666"}MouseArea {id: mouseAreaIdanchors.fill: parentonClicked: {containerRectId.buttonClicked()                                     // 触发信号}}}}
}

四、使用Loader动态加载组件

  Loader 用来动态加载 QML 组件。我们可以把 Loader 作为占位符使用,在需要显示某个元素时,才使用 Loader 把它加载进来。

  我们可以使用 Loadersource 属性 加载一个 QML 文档,也可以通过其 sourceComponent 属性 加载一个 Component 对象。当 LoadersourcesourceComponent 属性发生变化时,它之前加载的 Component 会自动销毁,新对象会被加载。将 source 设置为一个 空字符串 或将 sourceComponent 设置为 undefined,将会 销毁当前加载的对象,相关的资源也会被释放,而 Loader 对象则变成一个空对象。

  Loaderitem 属性 指向它加载的组件的顶层 Item。对于 Loader 加载的 Item,它暴露出来的接口,如属性、信号等,都可以通过 Loaderitem 属性来访问。

  虽然 Loader 本身是 Item 的派生类,但没有加载 ComponentLoader 对象是不可见的,没什么实际的意义,只是个占位符号,而一旦你加载了一个 ComponentLoader 的大小、位置等属性却可以影响它所加载的 Component

  如果你没有显式指定 Loader 的大小,那么 Loader 会将自己的尺寸调整为与它加载的可见 Item 的尺寸一致。如果 Loader 的大小通过 widthheight或锚布局显式设置了,那么它加载的可见 Item 的尺寸会被调整以便适应 Loader 的大小。不管是哪种情况,Loader 和它所加载的 Item 具有相同的尺寸,这确保你使用锚来布局 Loader 就等同于布局它加载的 Item

  如果我们要加载的 Component 比较大,则可能比较卡顿。此时你可以设置 asynchronous 属性为 true开启异步加载模式,当 status(枚举值)的值为 Loader.Ready 时表示 已经加载完毕status 属性的取值如下:

Loader.Null
Loader.Ready 
Loader.Loading
Loader.Error

  如果 Loader 加载的 Item处理按键事件,那么必须将 Loader 对象的 focus 属性设置为 true。又因为 Loader 本身也是一个焦点敏感的对象,所以如果它加载的 Item 处理了按键事件,则应当将事件的 accepted 属性设置为 true,以免已经被吃掉的事件再传递给 Loader

  修改 template.qml 文件的内容。

import QtQuick.Window// Window控件表示一个顶级窗口
// 在QML中,元素是通过大括号{}内的属性来配置的。
Window {width: 800                                                                  // 窗口的宽度height: 600                                                                 // 窗口的高度visible: true                                                               // 显示窗口color: "lightgray"// 自定义一个Componoent,需要手动加载才会显示Component {// Component不能定义除id以外的其它属性id: buttonComponentId// Component只能有一个顶层ItemRectangle {id: containerRectIdwidth: buttonTextId.implicitWidth + 60height: buttonTextId.implicitHeight + 20color: "#99CCFF"// 为内部的Text元素提供一个别名属性,方便在外部设置按钮的文本property alias buttonText: buttonTextId.textsignal buttonClicked()                                              // 自定义一个信号border {width: 1color: "#666666"}Text {id: buttonTextIdanchors.centerIn: parenttext: "按钮"font.pointSize: 16color: "#FF6666"}MouseArea {id: mouseAreaIdanchors.fill: parentonClicked: {containerRectId.buttonClicked()                                     // 触发信号}}}}Text {id: textIdanchors.centerIn: parentfont.pointSize: 32color: "#FF6666"}Row {spacing: 20Loader {id: firstButtonIdsourceComponent: buttonComponentId                                  // 加载一个Component对象asynchronous: true                                                  // 异步加载// 加载完成后会触发loaded信号onLoaded: {var customButton = firstButtonId.item                           // 获取加载组件顶层的Item对象customButton.buttonText = "第一个按钮"customButton.buttonClicked.connect(function() {textId.text = "第一个按钮被点击了"})}}Loader {id: secondButtonIdsourceComponent: buttonComponentId                                  // 加载一个Component对象asynchronous: true                                                  // 异步加载// 加载完成后会触发loaded信号onLoaded: {var customButton = secondButtonId.item                          // 获取加载组件顶层的Item对象customButton.buttonText = "第二个按钮"customButton.buttonClicked.connect(function() {textId.text = "第二个按钮被点击了"})}}}
}

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

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

相关文章

php网站的特点网站图标素材图片

作业1:设计界面 使用手动连接,将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中,在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中,在槽函数中判断ui界面上输入的账号是否为"admin…

深入解析:板凳-------Mysql cookbook学习 (九--2)

深入解析:板凳-------Mysql cookbook学习 (九--2)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&quo…

20251006 模拟测 总结

\(\mathcal{Preface}\) 分数 \(90+100+100+30=320\)。 挂完了,呜。 \(\mathcal{Problem \space{} A}\) Tag:诈骗,循环。 减法可以出负数,我们希望最后的值最大,可以一开始用最小的值去减其他所有值,但是保留任意…

数据源切换之道

深入探讨SpringBoot动态数据源切换的两种核心实现:MyBatis插件与SpringAOP。从原理剖析到实战演练,从性能对比到生产避坑,为你提供全方位的数据源切换解决方案。大家好,我是 Mr.Sun,一名热爱技术和分享的程序员。…

个人网站 网站教程做网站用php吗

样例简介 智能煤气检测系统通过实时监测环境中烟雾浓度,当一氧化碳浓度超标时,及时向用户发出警报。在连接网络后,配合数字管家应用,用户可以远程配置智能煤气检测系统的报警阈值,远程接收智能煤气检测系统报警信息。…

网站制作有哪些企业做医疗健康类网站需要资质吗

一直以来听的多了,什么UDP广播之类的,不过自己一直没有试验过,这次闲来无聊,于是测试了一下。网上说的其实并不是非常的正确,流传着不少的错误言论,这次自己动手测试了一下,没想到比我想象中的还…

完整教程:tryhackme——Abusing Windows Internals(进程注入)

完整教程:tryhackme——Abusing Windows Internals(进程注入)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "C…

向量存储vs知识图谱:LLM记忆系统技术选型

LLM本质上是无状态的,如果你了解HTTP协议就很好理解这个概念,但是如果你没接触过这,那么可以理解成它们没有短期记忆能力,每次和LLM交互,都得把之前的对话重新喂给它。 短期记忆或者说状态管理其实很好处理,拿几…

QBXT2025S刷题 Day5

今天更废了。 \(30pts\ rk84\)。 今天的题 T1 机房大部分人都做出来了,可是我只是打了个暴力(还没拿分)。 这道题其实可以把 \((b_1,b_2,b_3,b_4)\) 分为 \((b_1,b_2),(b_3,b_4)\) 两个部分。 这样的话,我们就可以…

做视频网站需要什么软件物流如何做网站

🌈个人主页:聆风吟 🔥系列专栏:图解数据结构、算法模板 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 一. ⛳️算法的定义二. ⛳️算法的特性2.1 🔔输入输出2.2 🔔输入输出2.3 &…

以人类演示视频为提示,学习可泛化的机器人策略 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

card

#include <bits/stdc++.h> using namespace std; #define P pair<char, char> #define mp(x, y) make_pair(x, y)vector< P > oper_list; const int len = 4; const int wide = 4; const int _size …

济宁企业网站建设wordpress页面发布不

打开题目 几次尝试&#xff0c;发现输1 1"&#xff0c;页面都会回显NO,Wrong username password&#xff01;&#xff01;&#xff01; 只有输入1&#xff0c;页面报错&#xff0c;说明是单引号的字符型注入 那我们万能密码试试能不能登录 1 or 11 # 成功登录 得到账号…

网站的建设及维护报告闵行做网站公司铝棒易站公司

目录 1.什么是互联网 2.互联网的发展历史 3.中国互联网的发展历程 4.互联网对人们生活的影响 5.互联网给人类带来了哪些负面影响 1.什么是互联网 互联网&#xff08;Internet&#xff09;是一个全球性的计算机网络系统&#xff0c;它连接了数十亿台计算机和其他设备。它是由…

Ai元人文系列:领域协同深耕:构建人机价值共生的文明实践框架

Ai元人文系列:领域协同深耕:构建人机价值共生的文明实践框架 引言:从割裂到共生的文明演进 我们正站在一个历史性的十字路口。数字技术的浪潮以前所未有的力量重塑着人类社会的基本结构,而人工智能的出现更是将这场…

如何监测光伏系统中的电能质量挑战?分布式光伏电能质量解决方案

如何监测光伏系统中的电能质量挑战?分布式光伏电能质量解决方案pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "C…

NFL统一数据生态系统技术架构解析

本文深入解析NFL如何通过统一数据生态系统提升运营效率,涵盖数据治理、数据工程、数据解决方案等五大技术支柱,实现从球员安全到球迷互动的全方位数据驱动决策。NFL统一数据生态系统:从球员安全到球迷互动 NFL正在通…

网站开发和运营维护兰州广告设计制作公司

文章目录一、基础准备1. 技术选型2. 源码克隆3. 安装依赖4. 将 RuoYi-Cloud 项目导入到 IDEA5. 安装启动Mysql6. 安装启动Redis7. 创建数据库&#xff0c;执行 SQL脚本文件二、安装与配置 nacos2.1. 下载nacos2.2. 安装 nacos2.3. nacos持久化配置2.4. 执行脚本文件2.5. nacos连…

大型网站后台登录地址一般是如何设置的虚拟主机购买网站

字典是具有指定数字或键的特定数据集或组。在 Python 以外的编程语言中&#xff0c;它们也被称为哈希映射或关联数组。 一般来说&#xff0c;它是键值对的形式&#xff0c;就像现实世界的字典一样。 要创建字典&#xff0c;请从左括号开始&#xff0c;添加键并键入一个冒号。…