玩转Qml(3)-换皮肤
![](/assets/blank.gif)
- 简介
- 效果预览
- 必要的基础
- QObject自定义属性
- 全局单例
- 实现
- 皮肤的配置和原理
- 皮肤选择器
- 带三角形尖尖的弹窗组件
简介
本文是《玩转Qml》系列文章的第三篇,涛哥将教大家,如何在Qml中实现动态换皮肤。顺带会分享一些Qt小技巧。
源码
《玩转Qml》系列文章,配套了一个优秀的开源项目:TaoQuick
github https://github.com/jaredtao/TaoQuick
访问不了或者速度太慢,可以用国内的镜像网站gitee
https://gitee.com/jaredtao/TaoQuick
效果预览
效果类似于网易云音乐
![](/assets/blank.gif)
顺便说一下,这是涛哥创建的TaoQuick项目,后续的各种组件、效果会全部集中在这个项目里。
文章中涉及的代码,都会先贴出来。整个工程的代码,在积累到一定程度后,会开放在github上。
必要的基础
可能有读者会疑惑,涛哥前两篇文章还在讲如何封装基础组件,这第三篇直接就来换皮肤?是不是跨度有点大?
其实换皮肤是一个很基础的功能,如果要做最好在项目初期就做起来,后期想要做换皮肤会困难一些(工作量大)。
如果你的项目做了很多组件化的封装,再做换皮肤会轻松一些。
QObject自定义属性
Qml中有一个类型叫QtObject,涛哥非常喜欢使用这个类型。
以前在写Qt/C++代码中的自定义QObject时,经常需要写一些自定义的Q_PROPERTY,以及实现set、get函数、change信号
如果纯手工写,挺累人的,涛哥曾写过自动生成器,相信很多人也写过类似的工具。
后来涛哥发现,QtCreator有自动生成的功能,只要写上Q_PROPERTY那一行,再用右键菜单生成即可,
高效率人士也可以使用快捷键,光标放在Q_PROPERTY上,按Alt + Enter。
![](/assets/blank.gif)
有时候需要把set函数的参数改成const T &类型来减少内存拷贝,并把函数实现移动到cpp文件中。(这都是C++的诟病)
然而,在Qml中,有更加方便的QtObject,
Item {QtObject { //定义一个QtObject,相当于Qt/c++代码中的QObjectid: dataObjproperty string name: "Hello" //这就定义了一个string类型的属性name,初始值设为"Hello"//定义完了,已经自带了onNameChanged信号。name被重新赋值时会触发信号//给这个信号写一个处理函数,就相当于连接上了槽函数。onNameChanged: {console.info("name:", name)}}...Button {...onClicked: { //演示: 按钮按下时,修改前面QtObject的name属性dataObj.name = "World"; }}...
}
(哈哈,工作量和心理负担一下子减轻了很多,头发的数量也能保住了。再也不想回去写Qt/C++的属性了。)
全局单例
涛哥写了一个单独的qml文件,顶层就是一个QtObject类型,里面会有一大堆属性。
颜色、字体一类的配置都在这里。
// GlobalConfig.qml
import QtQuick 2.0
QtObject {property color titleBackground: "#c62f2f" //标题栏的背景色property color background: "#f6f6f6" //标题栏之外的部分的背景色property color reserverColor: "#ffffff" //与背景色相反的对比色property color textColor: "black" //文本颜色}
然后在main.qml中实例化它
// main.qml
Item {width: 800height: 600GlobalConfig {id: gConfig}...
}
Qml有个特性,子页面实例可以通过id访问父页面中的实例,读 写其属性、调用其函数。
在main.qml中实例化的对象,相当于是全局的了,它的id是可以在所有main.qml的子页面中访问到的。
(当然还有一种方式,通过qmldir指定单例,这种留着后面再说)
实现
皮肤的配置和原理
下面是TaoQuick中使用的gConfig
// GlobalConfig.qml
QtObject {property color titleBackground: "#c62f2f"property color background: "#f6f6f6"property color reserverColor: "#ffffff"property color textColor: "black"property color splitColor: "gray"property int currentTheme: 0onCurrentThemeChanged: {var t = themes.get(currentTheme)titleBackground = t.titleBackgroundbackground = t.backgroundtextColor = t.textColor}readonly property ListModel themes: ListModel {ListElement {name: qsTr("一品红")titleBackground: "#c62f2f"background: "#f6f6f6"textColor: "#5c5c5c"}ListElement {name: qsTr("高冷黑")titleBackground: "#191b1f"background: "#222225"textColor: "#adafb2"}ListElement {name: qsTr("淑女粉")titleBackground: "#faa0c5"background: "#f6f6f6"textColor: "#5c5c5c"}ListElement {name: qsTr("富贵金")titleBackground: "#fed98f"background: "#f6f6f6"textColor: "#5c5c5c"}ListElement {name: qsTr(" 清爽绿")titleBackground: "#58c979"background: "#f6f6f6"textColor: "#5c5c5c"}ListElement {name: qsTr("苍穹蓝")titleBackground: "#67c1fd"background: "#f6f6f6"textColor: "#5c5c5c"}}
}
涛哥在所有的Page页面中,相关颜色设置都绑定到gConfig的相应属性上。
那么换皮肤,只需要修改gConfig中的颜色相关属性即可。因为修改属性时会触发change信号,而所有的Page都绑定了
gConfig的属性,会自动在发生change时重新读属性,修改后的颜色自动就生效了。
这里顺带说一下,主题的颜色相关属性越少越好,因为太多了不容易识别、不好维护,
之前的文章《玩转Qml(1)-从按钮开始》中提到的Qt.lighter和Qt.darker,
就是一种减少颜色属性数量的神器。
皮肤选择器
再来看一下,涛哥参考 网易云音乐 做的皮肤选择器
TImageBtn { //图片按钮,参考文章1width: 20height: 20anchors.verticalCenter: parent.verticalCenterimageUrl: containsMouse ? "qrc:/Image/Window/skin_white.png" : "qrc:/Image/Window/skin_gray.png"onClicked: {skinBox.show()}TPopup { //自定义的弹窗,带三角尖尖的那个。id: skinBoxbarColor: gConfig.reserverColorbackgroundWidth: 280backgroundHeight: 180contentItem: GridView {anchors.fill: parentanchors.margins: 10model: gConfig.themescellWidth: 80cellHeight: 80delegate: Item {width: 80height: 80Rectangle { //表示主题色的色块anchors.fill: parentanchors.margins: 4height: widthcolor: model.titleBackground}Rectangle { //主题色边框,鼠标悬浮时显示anchors.fill: parentcolor: "transparent"border.color: model.titleBackgroundborder.width: 2visible: a.containsMouse}Text { //主题名字anchors {left: parent.leftbottom: parent.bottomleftMargin: 8bottomMargin: 8}color: "white"text: model.name}Rectangle { //右下角圆圈圈,当前选中的主题x: parent.width - widthy: parent.height - heightwidth: 20height: widthradius: width / 2color: model.titleBackgroundborder.width: 3border.color: gConfig.reserverColorvisible: gConfig.currentTheme === index}MouseArea { //鼠标状态id: aanchors.fill: parenthoverEnabled: trueonClicked: { //切主题操作gConfig.currentTheme = index}}}}}
}
带三角形尖尖的弹窗组件
// TPopup.qml
import QtQuick 2.9
import QtQuick.Controls 2.5
Item {id: rootanchors.fill: parentproperty alias popupVisible: popup.visibleproperty alias contentItem: popup.contentItemproperty color barColor: "white"property alias backgroundItem: backgroundproperty real backgroundWidth: 200property real backgroundHeight: 160property color borderColor: barColorproperty real borderWidth: 0property real verticalOffset: 20//矩形旋转45度,一半被toolTip遮住(重合),另一半三角形和ToolTip组成一个带箭头的ToolTipRectangle {id: barvisible: popup.visiblerotation: 45width: 16height: 16color: barColor//水平居中anchors.horizontalCenter: parent.horizontalCenter//垂直方向上,由ToolTip的y值,决定位置anchors.verticalCenter: parent.bottomanchors.verticalCenterOffset: verticalOffset}Popup {id: popupwidth: backgroundWidthheight: backgroundHeightbackground: Rectangle {id: backgroundcolor: barColorradius: 8border.color:borderColorborder.width: borderWidth}}function show() {popup.x = (root.width - popup.width) / 2popup.y = root.height + verticalOffsetpopupVisible = true}function hide() {popupVisible = false}
}
玩转Qml(3)-换皮肤相关推荐
- 玩转Qml(12)-再谈动态国际化
简介 源码 效果预览 Qt本身的国际化 存在翻译不全的问题 新的方案 关于批量翻译 总结 简介 本文是<玩转Qml>系列文章的第十二篇,主要讨论多国语言动态翻译. 之前分享过使用Qt自带翻 ...
- Asp.Net下通过切换CSS换皮肤
换皮肤的方式有很多种,最简单的通常就是切换页面CSS,而CSS通常写在外部CSS文件里.那么切换css其实就是更换html里的link href路径.我在网上搜索了下.一般有两种方式: 1,在页面放一 ...
- 3D模型“换皮肤”有多简单?也就一句话的事
丰色 发自 凹非寺 量子位 报道 | 公众号 QbitAI 给灰突突的3D模型加"新皮肤",这事儿能有多简单? 现在,只需要一句话就能搞定. 看! 一个普通小台灯,给个" ...
- html背景自动换,html页面换皮肤颜色、背景图片(更换页面背景,常驻缓存)刷新保存...
利用样式文件,使网页能够更换不同的主题风格,这个只是简单的小列子,更换了背景图,和字体颜色,更换主题的基本原理是这样的.通过更改,link标签里的href属性,加载不同的样式文件.这里还用到了一款JQ ...
- Android UI换皮肤或 白天黑夜模式
Android UI换皮肤或 白天黑夜模式 UI换皮肤或白天黑夜模式,从产品上来看,是两种不同产品设计模式:白天黑夜模式只有两种模式:而换皮肤可以有多套,可以进行商业化,并盈利. > 白天夜间模 ...
- 用SkinMagic工具包创建换皮肤程序
<script type="text/javascript"> </script> <script src="http://pagead2. ...
- 玩转Qml(18)-用户向导
简介 效果预览 源码 原理说明 需求说明 原理 Qml对象作用域 QObject对象树 实现 最小改动 获取焦点区域 找到对象 取坐标 向导页 向导组件 向导数据源 简介 很多现代化的软件,都会有向导 ...
- JavaScript+Css+Html实现网页换皮肤功能
描述:JavaScript+Css+Html实现网页换皮肤功能 原理:使用不同网页背景保存在不同CSS里面,当点击切换的时候通过JavaScript将原来的样式表改为新的CSS就可以完成换肤功能 代码 ...
- vivo换手机云服务器,vivo玩机指南:换新机数据不用烦,云服务一步搞定
原标题:vivo玩机指南:换新机数据不用烦,云服务一步搞定 在遍地支持手机支付的网络时代,手机是其他无可替代的一样电子产品.每个品牌,每个型号,里面的功能都是不一样的.那么身为一个资深vivo手机粉, ...
最新文章
- java中调用kettle作业以及生成web service 接口
- I.MX6 WIFI wireless_tools 移植
- Apache SparkStreaming 简介和编程模型
- poj 1330 Nearest Common Ancestors LCA/DFS
- python基础知识下载_Python基础知识(一)
- 【clickhouse】clickhouse 一些博客链接
- 两个not exists_分享两个冷门但又超实用的 Vim 使用技巧!
- python降维可视化 自编码_deep learning 自编码算法详细理解与代码实现(超详细)...
- 【VMCloud云平台】SCOM配置(十五)-启用SCOM日志审计(ACS)
- 考研编程练习---StringMatching(后缀表达式)
- Atitit 人脸识别 眼睛形态 attilax总结 可以按照大小来分类。。或者按照形态来分类 眼睛的类型、分类。包括杏眼,狐狸眼,铜铃眼,龙眼,丹凤眼和小鹿眼等等。 月牙眼 笑起来。。吊梢
- APP自动化测试-3. Appium元素定位与等待
- 题解1205汉诺塔问题
- 怎么压缩pdf文件大小?
- 31.SUM() 函数
- java共享文件夹SMB1服务报错jcifs.smb.SmbException: Failed to connect: 0.0.0.0<00>/122.168.23.26
- windows访问控制列表ACL
- 以下是一些常用的上位机开发工具:
- 【JDK7】新特性(8) 异步io/AIO
- Jump lattice 跳格子
热门文章
- MTK LCD背光驱动——背光芯片
- vmware 16 安装 macOS15
- android iphone手机分辨率尺寸比例整理
- 武汉大学图书馆随书光盘管理系统
- 站外seo优化有用吗?值得投入时间和精力吗?
- 锐龙用vm搭建linux,玩vmware的话主机千万别用AMD的芯片
- linux恢复rm命令,linux下rm删除与恢复
- VSTS 更名为 Azure DevOps
- 安装TortoiseSVN时报错Could not write value {30351348-7B7D-4FCC-81B4-1E394CA267EB} to key……的解决方法
- html更改表单按钮文字,HTML进阶应用技巧(十)用好表单的按钮