qml基础学习 基础概念
一、概括
学习qt已有2年多的时间,从qt4.7开始使用直到现在正在使用的qt5.6,基本都在windows机器上做开发。最近有意向看了下qt的qml部分,觉着还是挺不错的,毕竟可以做嵌入式移动端产品的部分,还是值的一学。后来在网上看了一些资料,算是初步了解了下qml,所以想就自己学习的过程做以记录,也方便自己理解,如果你有机会看到这篇文章,那么我认为你也是来学习qml的,如果你已经是一个有很强qml开发经验的老手,那么这篇文章和接下来的qml学习系列的文章你都不用看下去了,呵呵。。。
关于qml的由来,个人觉着Qt的Script、Quick、QML的关系与总结讲的不错,有兴趣的同学可以去看下。
qml的学习过程我主要是以Qt 学习之路 2博客和QmlBook-In-Chinese这本书为主,同时在做小示例的时候查阅帮助文档。每个人的学习方式都不太一样,如果你有更好的办法可以留言。
二、效果预览
如下有4张效果图,分别是4个小示例,关于demo后续章节会有解说,但是都是以代码中的注解为主,有兴趣的同学也可以直接下载示例程序,使用qt提供的qmlscene.exe来直接执行qml文件,或者qmlviewer.exe也可以预览qml文件。
图1 转动的组件
图2 红绿灯1
图3 红绿灯2
图4 GridView使用
三、学习qml必备
- 基本元素
- 组件,基本元素的复合
- 定位器(布局)
- 元素布局,锚
- 输入元素,一行和多行
- quick现有组件
- 模型和视图
- Canvas元素
1、基本元素
QML 基本元素可以分为可视元素和不可视元素两类。可视元素:Item
、Rectangle
、Text
、Image
;不可见元素:MouseArea
。关于MouseArea是不可见元素这一点我需要强调一下,因为上边我提到的两篇学习文章都没有说清楚,图5是qt5.7的帮助文档截图,从图中我们一眼就能看出结果,MouseArea确实是不可见元素。
图5 MouseArea帮助文档
关于基本元素我觉着qmlbook这本书相关章节的最后一段说的很有意思,特此说明,如图6所示
图6 qml显示和交互分开
理解这些基本元素,你可以认为他们是一个个被封装好的类,而且他们有非常之多的属性,这里我就不介绍了,因为帮助文档说的太清楚了。
2、组件
组件其实就是基本元素的复合,放到一个单独的文件,方便我们以后重用,关于怎么创建组件,本节的后续我会给出自己做的示例程序,代码很简单只是为了说明问题
3、定位器
定位器主要有 Row
、Column
、Grid
和Flow
等。
4、元素布局
除了定位器,我们还可以使用锚(anchor)来布局元素
5、输入元素
键盘输入的两个元素:TextInput
和TextEdit
。TextInput为一行输入,TextEdit为多行输入
6、quick组件
如表1是Qt Quick Controls 1.1 提供的组件
ApplicationWindow | 对应QMainWindow ,提供顶层应用程序窗口 |
MenuBar | 对应QMenuBar ,提供窗口顶部横向的菜单栏 |
StatusBar | 对应QStatusBar ,提供状态栏 |
ToolBar | 对应QToolBar ,提供工具栏,可以添加ToolButton 和其它组件 |
Action | 对应QAction ,提供能够绑定到导航和视图的抽象的用户界面动作 |
导航和视图 | |
方便用户在一个布局中管理和显示其它组件 | |
ScrollView | 对应QScrollView ,提供滚动视图 |
SplitView | 对应QSplitter ,提供可拖动的分割视图布局 |
StackView | 对应QStackedWidget ,提供基于栈的层叠布局 |
TabView | 对应QTabWidget ,提供带有标签的基于栈的层叠布局 |
TableView | 对应QTableWidget ,提供带有滚动条、样式和表头的表格 |
控件 | |
控件用于表现或接受用户输入 | |
BusyIndicator | 提供忙等示意组件 |
Button | 对应QPushButton ,提供按钮组件 |
CheckBox | 对应QCheckBox ,提供复选框 |
ComboBox | 对应QComboBox ,提供下拉框 |
GroupBox | 对应QGroupBox ,提供带有标题、边框的容器 |
Label | 对应QLabel ,提供标签组件 |
ProgressBar | 对应QProgressBar ,提供进度条组件 |
RadioButton | 对应QRadioButton ,提供单选按钮 |
Slider | 对应QSlider ,提供滑动组件 |
SpinBox | 对应QSpinBox ,提供微调组件 |
Switch | 提供类似单选按钮的开关组件 |
TextArea | 对应QTextEdit ,提供能够显示多行文本的富文本编辑框 |
TextField | 对应QTextLine ,提供显示单行文本的纯文本编辑框 |
ToolButton | 对应QToolButton ,提供在工具栏上显示的工具按钮 |
ExclusiveGroup | 提供互斥 |
菜单 | |
用于构建菜单的组件 | |
Menu | 对应QMenu ,提供菜单、子菜单、弹出菜单等 |
MenuSeparator | 提供菜单分隔符 |
MenuItem | 提供添加到菜单栏或菜单的菜单项 |
StatusBar | 对应QStatusBar ,提供状态栏 |
ToolBar | 对应QToolBar ,提供工具栏,可以添加ToolButton 和其它组件 |
表1 Qt Quick Controls 1.1组件
7、模型和视图
模型和视图其实属于qml的高级使用部分了,但是为了能早些理解qml的东西,我提前拿出一些简单的东西,预先学习下。
8、canvas画布
在早些qt4时代,qml只提供了几种基础元素,第一小节也说明了,有很多人期望的圆角矩形,椭圆和圆,但是最终官方没有给出具体的元素,如果是要做这些组件,那么就需要设计师给切图。到了qt5,官方提供了canvas画布,这个画布可以实现复杂的绘图操作,并且画布元素是基于HTML5的画布元素来完成的。支持画笔,填充,渐变,文本和绘制路径创建命令。
四、小示例
接下里就是第二节所展示的效果图对于代码讲解了,那我也就按照上图展示的顺序一个个讲解代码
1、基础组件讲解
在开始示例讲解之前,我先说下我自己封装的一个小组件,代码量很少,只为说明问题,具体请看diamante
import QtQuick 2.5 // 圆角矩形框矩形框,支持点击
Rectangle {
property alias text: name.text;//导出文本变量
property alias textColor: name.color;//导出文本颜色 id: root;
width: ;
height: ;
radius:;
antialiasing: true;
signal clicked();//自定义信号 外部可以通过onClicked接收 MouseArea
{
width: root.width;
height: root.height; onClicked:
{
//鼠标点击时发送消息 并输入日志
root.clicked();
console.log("rectangle clicked");
}
} Text
{
id: name;
text: "";
color: "black";
anchors.centerIn: parent;
}
}
2、旋转的风车,代码里有多种方式实现矩形旋转,具体使用那一种就由个人喜好了
import QtQuick 2.0
import QtQuick.Window 2.0
import QtGraphicalEffects 1.0 import "../contrl" //导入自定义组件模块 Window {
id:root;
visible: true;
width: ;
height: ; //背景色窗口
Rectangle {
id: bg;
color:"lightsteelblue";
width: root.width;
height:root.height;
}
//鼠标点击背景色时停止旋转图形
MouseArea {
width: bg.width;
height: bg.height; onClicked: {
ro.pause();
}
} //自定义控件 通过import导入
Rect
{
id: roundItem;
anchors.centerIn: parent;
//渐变填充矩形
ConicalGradient
{
anchors.fill: parent
gradient: Gradient {
GradientStop { position: 0.0; color: "lightsteelblue" }
GradientStop { position: 1.0; color: "blue" }
}
}
//旋转动画1 程序刚启动会执行 原因未知
// NumberAnimation on rotation {
// loops:Animation.Infinite;
// from:0;
// to:360;
// duration: 1000;
// } //旋转动画2 配合wheel.rotation = 360;使用 动画 不能循环执行
// Behavior on rotation {
// NumberAnimation {
// loops:Animation.Infinite;//无效
// duration: 1000;
// }
// } //旋转动画3 相比于动画1 在属性中主动指明了target和property
// NumberAnimation {
// id:ro;
// loops:Animation.Infinite;
// property: "rotation";
// target:roundItem;
// from:0;
// to:360;
// duration: 1000;
// } //旋转动画4 和动画1是一样的 因为RotationAnimation和NumberAnimation都是继承自PropertyAcimation
//因此RotationAnimation动画可以实现和动画2一样的效果,使用RotationAnimation
// RotationAnimation on rotation {
// loops: Animation.Infinite;
// from: 0;
// to: 360;
// duration: 1000;
// } //旋转动画5
RotationAnimation {
id:ro;
target:roundItem;
loops: Animation.Infinite;
from: ;
to: ;
duration: ;
} onClicked: {
if (ro.paused)
{
ro.resume();
}
else
{
ro.start();
}
}
}
}
3、红绿灯,下述代码红色的的切换时通过鼠标单击进行
import QtQuick 2.0
import QtQuick.Window 2.0
import QtGraphicalEffects 1.0 import "../contrl" Window
{
function dosomething()//测试script脚本运行效果
{
console.log("do something");
} id:root;
visible: true;
width: ;
height: ; Rectangle
{
id:rootRect;
width: root.width;
height:root.height;
anchors.centerIn:parent; Row
{
id:ligheGroup;
spacing: ;
states:
[
State {
name: "red"
// StateChangeScript {name: "myScript"; script: dosomething(); } //可以正常调用
PropertyChanges {
target: redLight; color:"red";
}
PropertyChanges {
target: greenLight; color:"black";
}
PropertyChanges {
target: yellowLight; color:"black";
}
},
State {
name: "green"
PropertyChanges {
target: redLight; color:"black";
}
PropertyChanges {
target: greenLight; color:"green";
}
PropertyChanges {
target: yellowLight; color:"black";
}
},
State {
name: "yellow"
PropertyChanges {
target: redLight; color:"black";
}
PropertyChanges {
target: greenLight; color:"black";
}
PropertyChanges {
target: yellowLight; color:"yellow";
}
}
] anchors.centerIn:parent;
Rect//红灯
{
id:redLight;
color:"black";
radius: width/;
}
Rect//绿灯
{
id:greenLight;
color:"black";
radius: width/;
}
Rect//黄灯
{
id:yellowLight;
color:"black";
radius: width/;
} transitions:
[
Transition //提供从red状态到yellow状态的渐变过程
{
from: "red"
to: "yellow"
// ScriptAction { script: dosomething(); } //可以正常调用
ColorAnimation{ target: redLight; properties: "color";duration: ;}
ColorAnimation{ target: yellowLight; properties: "color";duration: ;}
}
]
}
property bool m_bIsRed : false;
MouseArea
{
anchors.fill: parent;
onClicked://鼠标点击时,状态切换
{
if (ligheGroup.state == "red"
|| ligheGroup.state == "green")
{
ligheGroup.state = "yellow";
}
else
{
if (parent.m_bIsRed == false)
{
ligheGroup.state = "red";
parent.m_bIsRed = true;
}
else
{
ligheGroup.state = "green";
parent.m_bIsRed = false;
}
}
}
}
}
}
4、红绿灯,不同于上述红绿灯,次红绿灯只需要鼠标单击触发运行,状态是由定时器来控制,红灯运行60秒,绿灯20秒,黄灯3秒,为了程序的迅速反应,在红灯和绿灯的时候定时器触发频率所有提高,具体请看代码,此处我只贴出定时器部分,如果需要整个运行程序,可自行下载demo。
property bool m_bIsRed : false;//是否是红灯亮
property int m_iTicker : ; Timer
{
id:redState;
interval: ;//每隔50毫秒触发一次,真实情况下本应该是1000毫秒一次
repeat: true;
triggeredOnStart: true;
property int count : ;//红灯秒数 onTriggered: {
if (lightGroup.state != "red")
{
lightGroup.state = "red";
root.m_bIsRed = true;
} ++m_iTicker;
redLight.text = count - m_iTicker;
if (count <= m_iTicker)//到达指定时间 重置计数器,并切换到黄灯定时器,关闭自身定时器
{
m_iTicker = ;
yellowState.start();
redState.stop();
}
}
}
Timer
{
id:yellowState;
interval: ;
repeat: true;
triggeredOnStart: true;
property int count : ;//黄灯秒数 onTriggered: {
if (lightGroup.state != "yellow")
{
lightGroup.state = "yellow";
}
++m_iTicker;
yellowLight.text = count - m_iTicker;
if (count <= m_iTicker)//到达指定时间 重置计数器,并切换到绿灯/红灯定时器,关闭自身定时器
{
m_iTicker = ;
if (m_bIsRed)
{
greenState.start();
}
else
{
redState.start();
}
stop();
}
}
}
Timer
{
id: greenState;
interval: ;//每隔150毫秒触发一次,真实情况下本应该是1000毫秒一次
repeat: true;
triggeredOnStart: true;
property int count : ;//绿灯秒数 onTriggered: {
if (lightGroup.state != "green")
{
lightGroup.state = "green";
root.m_bIsRed = false;
} ++m_iTicker;
greenLight.text = count - m_iTicker;
if (count <= m_iTicker)//到达指定时间 重置计数器,并切换到黄灯定时器,关闭自身定时器
{
m_iTicker = ;
yellowState.start();
greenState.stop();
}
}
}
5、日历窗口,代码量不大,有兴趣的可以看看,主要就是界面展示,如果想要做到动态的日历,需要对模型动态的增删,这个功能后续我们在完善。
import QtQuick 2.6
import QtQuick.Window 2.0
import QtGraphicalEffects 1.0 import "../contrl" Window
{
visible: true;
width: ;
height: ; Rectangle
{
id:root;
anchors.fill: parent;
width: root.width;
height: root.height;
color: "yellow"; //日期头
Row
{
id: weekname;
spacing: ;
padding: ; Repeater
{
model: ["周天", "周一", "周二", "周三", "周四", "周五", "周六"]
Rectangle
{
width: (root.width - * weekname.spacing - ) / ;
height:
radius:
color: "lightBlue"
Text
{
anchors.centerIn: parent
text: modelData
}
}
}
} //天
GridView
{
id: weekday;
boundsBehavior: Flickable.StopAtBounds;
anchors//布局
{
top: weekname.bottom;
left:root.left;
leftMargin:;
right: root.right;
rightMargin:;
bottom: root.bottom;
}
model: ;//天数 cellWidth: (root.width - ) / ;
cellHeight: (root.width - ) / ;
// Repeater
// {
// Rectangle
// {
// radius: 8;
// color: "lightBlue";
// Text
// {
// anchors.centerIn: parent;
// text: modelData;
// }
// }
// }
delegate: numberDelegate;
focus: true;//可以获取焦点
} Component//绘制代理
{
id: numberDelegate;
Rectangle
{
width: weekday.cellWidth;
height: weekday.cellHeight;
color: GridView.isCurrentItem ? "green" : "lightGreen"//根据是否是当前项设置颜色
border.color: Qt.lighter("green");
Text
{
anchors.centerIn: parent;
font.pixelSize: ;
text: index + ;//文本取索引值
}
}
}
}
}
补充:示例代码中:GridView中的repeater元素是不需要的,repeater是配合定位器使用的模型,因为每一个repeater都包含一个默认的绘制代理。
五、下载链接
注:这是qml学习系列的第一篇文章,后边我还会以这种示例的形式继续更新更多学习的进度,希望大家多多支持,有问题的小伙伴可以私信我。谢谢。。。
qml基础学习 基础概念的更多相关文章
- hadoop基础学习---基本概念
1.组成部分HDFS和MapReduce 2.HDFS这几架构
- qml基础学习 Canvas画笔
一.画布元素 自qt4.7发布qml以来,qml也在一直不断的完善中,在qt4时代使用qml时如果需要异形图,那我们只能让设计师来切图,这样的感觉是很不爽的,总感觉开发没有那么犀利.但是到了qt5这一 ...
- qml基础学习 模型视图(一)
一.理解qml模型和视图 qt的发展是迅速的,虽然在每一个release版本中或多或少都有bug,但是作为一个庞大的gui库,no,应该说是一个开发框架开说,qt已经算是做的相当好.qml部分是qt4 ...
- 分布式强化学习基础概念(Distributional RL )
分布式强化学习基础概念(Distributional RL) from: https://mtomassoli.github.io/2017/12/08/distributional_rl/ 1. Q ...
- C#学习基础概念二十五问
C#学习基础概念二十五问 1.静态变量和非静态变量的区别?2.const 和 static readonly 区别?3.extern 是什么意思?4.abstract 是什么意思?5.internal ...
- SQL 基础学习(2) Joining 和function , 作业没有做,需要看百宝箱。NOsql的概念
SQL 基础学习(2) Joining 可以同时关联(joining)多张表进行复杂的查询. 相比于用Rails捞出数据再用Ruby进行过滤组合,使用SQL更加高效,节能. 以下是 users has ...
- 现代3D图形编程学习-基础简介(1) (译)
本书系列 现代3D图形编程学习 基础简介 并不像本书的其他章节,这章内容没有相关的源代码或是项目.本章,我们将讨论向量,图形渲染理论,以及OpenGL. 向量 在阅读这本书的时候,你需要熟悉代数和几何 ...
- 如何从零基础学习VR
转载请声明转载地址:http://www.cnblogs.com/Rodolfo/,违者必究. 近期很多搞技术的朋友问我,如何步入VR的圈子?如何从零基础系统性的学习VR技术? 本人将于2017年1月 ...
- AspectJ基础学习之一简介(转载)
AspectJ基础学习之一简介(转载) 一.为什么写这个系列的博客 Aspectj一个易用的.功能强大的aop编程语言.其官网地址是:http://www.eclipse.org/aspectj/ ...
随机推荐
- Java中的受检异常
Java中的受检异常 Java提供了三种异常类型,受检异常(checked exception).运行时异常(runtime exception).错误(error).那么这受检异常在实际开发中又有什 ...
- RCP:给GEF编辑器添加网格和标尺。
网格和标尺效果如上图所示. 添加网格比较简单,也可以自己实现,主要思路是为编辑器添加一个GridLayer.但是还是建议参考eclipse自己的GEF样例来实现. 需要注意两个部分: 1.重写org. ...
- 【腾讯Bugly干货分享】React移动web极致优化
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/579083d1c9da73584b02587d 最近一个季度,我们都在为手Q家校 ...
- Linux1:Linux概述
为什么服务器尤其大型服务器都使用Linux系统 服务器尤其是大型服务器一般都使用Linux系统,有以下几点原因: 1.成本低,Linux操作系统是免费的 2.安全性好,Linux采取了许多的安全措施, ...
- Spring中Ordered接口简介
目录 前言 Ordered接口介绍 Ordered接口在Spring中的使用 总结 前言 Spring中提供了一个Ordered接口.Ordered接口,顾名思义,就是用来排序的. Spring是一个 ...
- [nRF51822] 4、 图解nRF51 SDK中的Schedule handling library 和Timer library
:nRF51822虽然是一个小型的单片机,但是能真正达到任意调用其官方驱动以及BLE协议栈的人还是奇缺的.据我所见,大都拿官方给的一个冗长的蓝牙低功耗心率计工程改的.之前我对于这个工程进行log跟踪, ...
- H5常用代码:适配方案5
此方案跟方案4是同一原理,也是通过REM实现的,能单独归类出一个方案,是因为它有一定的实用价值,当你遇到追求完美,追求到一像素的UI或者产品时,那此方案将解决你的困境. 方案5主要是用来解决一像素边框 ...
- salesforce 零基础学习(二十六)自定义图表chart简单介绍(使用apex和VF实现)
chart在报表中经常使用到,他可以使报表结果更加直观的展现给用户.salesforce支持VF和apex代码来更好的展示chart. chart分类:常用的图表样式有饼状图,柱状图,折线图,条形图, ...
- 【原创】NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示
申明:本文由作者基于日常实践整理,希望对初次接触MINA.Netty的人有所启发.如需与作者交流,见文签名,互相学习. 学习交流 更多学习资料:点此进入 推荐 移动端即时通讯交流: 215891622 ...
- JQuery uploadify 的使用
在Java WEB项目中用到了上传图片的功能,于是百度了一下,发现 uploadify 的出镜率很高,于是决定使用这个插件.结果昨天调试了一天没有成功,今天早上仔细想了想,觉得应该是调用js文件的原因 ...