• 简介
  • 效果预览
  • 必要的基础
    • QObject自定义属性
    • 全局单例
  • 实现
    • 皮肤的配置和原理
    • 皮肤选择器
    • 带三角形尖尖的弹窗组件

简介

本文是《玩转Qml》系列文章的第三篇,涛哥将教大家,如何在Qml中实现动态换皮肤。顺带会分享一些Qt小技巧。

源码

《玩转Qml》系列文章,配套了一个优秀的开源项目:TaoQuick

github https://github.com/jaredtao/TaoQuick

访问不了或者速度太慢,可以用国内的镜像网站gitee

https://gitee.com/jaredtao/TaoQuick

效果预览

效果类似于网易云音乐

顺便说一下,这是涛哥创建的TaoQuick项目,后续的各种组件、效果会全部集中在这个项目里。

文章中涉及的代码,都会先贴出来。整个工程的代码,在积累到一定程度后,会开放在github上。

必要的基础

可能有读者会疑惑,涛哥前两篇文章还在讲如何封装基础组件,这第三篇直接就来换皮肤?是不是跨度有点大?

其实换皮肤是一个很基础的功能,如果要做最好在项目初期就做起来,后期想要做换皮肤会困难一些(工作量大)。

如果你的项目做了很多组件化的封装,再做换皮肤会轻松一些。

QObject自定义属性

Qml中有一个类型叫QtObject,涛哥非常喜欢使用这个类型。

以前在写Qt/C++代码中的自定义QObject时,经常需要写一些自定义的Q_PROPERTY,以及实现set、get函数、change信号

如果纯手工写,挺累人的,涛哥曾写过自动生成器,相信很多人也写过类似的工具。

后来涛哥发现,QtCreator有自动生成的功能,只要写上Q_PROPERTY那一行,再用右键菜单生成即可,

高效率人士也可以使用快捷键,光标放在Q_PROPERTY上,按Alt + Enter。

有时候需要把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)-换皮肤相关推荐

  1. 玩转Qml(12)-再谈动态国际化

    简介 源码 效果预览 Qt本身的国际化 存在翻译不全的问题 新的方案 关于批量翻译 总结 简介 本文是<玩转Qml>系列文章的第十二篇,主要讨论多国语言动态翻译. 之前分享过使用Qt自带翻 ...

  2. Asp.Net下通过切换CSS换皮肤

    换皮肤的方式有很多种,最简单的通常就是切换页面CSS,而CSS通常写在外部CSS文件里.那么切换css其实就是更换html里的link href路径.我在网上搜索了下.一般有两种方式: 1,在页面放一 ...

  3. 3D模型“换皮肤”有多简单?也就一句话的事

    丰色 发自 凹非寺 量子位 报道 | 公众号 QbitAI 给灰突突的3D模型加"新皮肤",这事儿能有多简单? 现在,只需要一句话就能搞定. 看! 一个普通小台灯,给个" ...

  4. html背景自动换,html页面换皮肤颜色、背景图片(更换页面背景,常驻缓存)刷新保存...

    利用样式文件,使网页能够更换不同的主题风格,这个只是简单的小列子,更换了背景图,和字体颜色,更换主题的基本原理是这样的.通过更改,link标签里的href属性,加载不同的样式文件.这里还用到了一款JQ ...

  5. Android UI换皮肤或 白天黑夜模式

    Android UI换皮肤或 白天黑夜模式 UI换皮肤或白天黑夜模式,从产品上来看,是两种不同产品设计模式:白天黑夜模式只有两种模式:而换皮肤可以有多套,可以进行商业化,并盈利. > 白天夜间模 ...

  6. 用SkinMagic工具包创建换皮肤程序

    <script type="text/javascript"> </script> <script src="http://pagead2. ...

  7. 玩转Qml(18)-用户向导

    简介 效果预览 源码 原理说明 需求说明 原理 Qml对象作用域 QObject对象树 实现 最小改动 获取焦点区域 找到对象 取坐标 向导页 向导组件 向导数据源 简介 很多现代化的软件,都会有向导 ...

  8. JavaScript+Css+Html实现网页换皮肤功能

    描述:JavaScript+Css+Html实现网页换皮肤功能 原理:使用不同网页背景保存在不同CSS里面,当点击切换的时候通过JavaScript将原来的样式表改为新的CSS就可以完成换肤功能 代码 ...

  9. vivo换手机云服务器,vivo玩机指南:换新机数据不用烦,云服务一步搞定

    原标题:vivo玩机指南:换新机数据不用烦,云服务一步搞定 在遍地支持手机支付的网络时代,手机是其他无可替代的一样电子产品.每个品牌,每个型号,里面的功能都是不一样的.那么身为一个资深vivo手机粉, ...

最新文章

  1. java中调用kettle作业以及生成web service 接口
  2. I.MX6 WIFI wireless_tools 移植
  3. Apache SparkStreaming 简介和编程模型
  4. poj 1330 Nearest Common Ancestors LCA/DFS
  5. python基础知识下载_Python基础知识(一)
  6. 【clickhouse】clickhouse 一些博客链接
  7. 两个not exists_分享两个冷门但又超实用的 Vim 使用技巧!
  8. python降维可视化 自编码_deep learning 自编码算法详细理解与代码实现(超详细)...
  9. 【VMCloud云平台】SCOM配置(十五)-启用SCOM日志审计(ACS)
  10. 考研编程练习---StringMatching(后缀表达式)
  11. Atitit 人脸识别 眼睛形态 attilax总结 可以按照大小来分类。。或者按照形态来分类 眼睛的类型、分类。包括杏眼,狐狸眼,铜铃眼,龙眼,丹凤眼和小鹿眼等等。 月牙眼 笑起来。。吊梢
  12. APP自动化测试-3. Appium元素定位与等待
  13. 题解1205汉诺塔问题
  14. 怎么压缩pdf文件大小?
  15. 31.SUM() 函数
  16. java共享文件夹SMB1服务报错jcifs.smb.SmbException: Failed to connect: 0.0.0.0<00>/122.168.23.26
  17. windows访问控制列表ACL
  18. 以下是一些常用的上位机开发工具:
  19. 【JDK7】新特性(8) 异步io/AIO
  20. Jump lattice 跳格子

热门文章

  1. MTK LCD背光驱动——背光芯片
  2. vmware 16 安装 macOS15
  3. android iphone手机分辨率尺寸比例整理
  4. 武汉大学图书馆随书光盘管理系统
  5. 站外seo优化有用吗?值得投入时间和精力吗?
  6. 锐龙用vm搭建linux,玩vmware的话主机千万别用AMD的芯片
  7. linux恢复rm命令,linux下rm删除与恢复
  8. VSTS 更名为 Azure DevOps
  9. 安装TortoiseSVN时报错Could not write value {30351348-7B7D-4FCC-81B4-1E394CA267EB} to key……的解决方法
  10. html更改表单按钮文字,HTML进阶应用技巧(十)用好表单的按钮