一、概括

学习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必备

  1. 基本元素
  2. 组件,基本元素的复合
  3. 定位器(布局)
  4. 元素布局,锚
  5. 输入元素,一行和多行
  6. quick现有组件
  7. 模型和视图
  8. Canvas元素

1、基本元素

QML 基本元素可以分为可视元素和不可视元素两类。可视元素:ItemRectangleTextImage;不可见元素:MouseArea。关于MouseArea是不可见元素这一点我需要强调一下,因为上边我提到的两篇学习文章都没有说清楚,图5是qt5.7的帮助文档截图,从图中我们一眼就能看出结果,MouseArea确实是不可见元素。

图5 MouseArea帮助文档

关于基本元素我觉着qmlbook这本书相关章节的最后一段说的很有意思,特此说明,如图6所示

图6 qml显示和交互分开

理解这些基本元素,你可以认为他们是一个个被封装好的类,而且他们有非常之多的属性,这里我就不介绍了,因为帮助文档说的太清楚了。

2、组件

组件其实就是基本元素的复合,放到一个单独的文件,方便我们以后重用,关于怎么创建组件,本节的后续我会给出自己做的示例程序,代码很简单只是为了说明问题

3、定位器

定位器主要有 RowColumnGridFlow等。

4、元素布局

除了定位器,我们还可以使用锚(anchor)来布局元素

5、输入元素

键盘输入的两个元素:TextInputTextEdit。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学习系列的第一篇文章,后边我还会以这种示例的形式继续更新更多学习的进度,希望大家多多支持,有问题的小伙伴可以私信我。谢谢。。。

如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!! 

 

很重要--转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。

qml基础学习 基础概念的更多相关文章

  1. hadoop基础学习---基本概念

    1.组成部分HDFS和MapReduce 2.HDFS这几架构

  2. qml基础学习 Canvas画笔

    一.画布元素 自qt4.7发布qml以来,qml也在一直不断的完善中,在qt4时代使用qml时如果需要异形图,那我们只能让设计师来切图,这样的感觉是很不爽的,总感觉开发没有那么犀利.但是到了qt5这一 ...

  3. qml基础学习 模型视图(一)

    一.理解qml模型和视图 qt的发展是迅速的,虽然在每一个release版本中或多或少都有bug,但是作为一个庞大的gui库,no,应该说是一个开发框架开说,qt已经算是做的相当好.qml部分是qt4 ...

  4. 分布式强化学习基础概念(Distributional RL )

    分布式强化学习基础概念(Distributional RL) from: https://mtomassoli.github.io/2017/12/08/distributional_rl/ 1. Q ...

  5. C#学习基础概念二十五问

    C#学习基础概念二十五问 1.静态变量和非静态变量的区别?2.const 和 static readonly 区别?3.extern 是什么意思?4.abstract 是什么意思?5.internal ...

  6. SQL 基础学习(2) Joining 和function , 作业没有做,需要看百宝箱。NOsql的概念

    SQL 基础学习(2) Joining 可以同时关联(joining)多张表进行复杂的查询. 相比于用Rails捞出数据再用Ruby进行过滤组合,使用SQL更加高效,节能. 以下是 users has ...

  7. 现代3D图形编程学习-基础简介(1) (译)

    本书系列 现代3D图形编程学习 基础简介 并不像本书的其他章节,这章内容没有相关的源代码或是项目.本章,我们将讨论向量,图形渲染理论,以及OpenGL. 向量 在阅读这本书的时候,你需要熟悉代数和几何 ...

  8. 如何从零基础学习VR

    转载请声明转载地址:http://www.cnblogs.com/Rodolfo/,违者必究. 近期很多搞技术的朋友问我,如何步入VR的圈子?如何从零基础系统性的学习VR技术? 本人将于2017年1月 ...

  9. AspectJ基础学习之一简介(转载)

    AspectJ基础学习之一简介(转载) 一.为什么写这个系列的博客   Aspectj一个易用的.功能强大的aop编程语言.其官网地址是:http://www.eclipse.org/aspectj/ ...

随机推荐

  1. Understanding ASP.NET MVC Filters and Attributes

    这篇文章把Asp.net MVC的filter介绍的很详细,值得收藏. http://www.dotnet-tricks.com/Tutorial/mvc/b11a280114-Understandi ...

  2. 如何快速把hdfs数据动态导入到hive表

    1. hdfs 文件   {"retCode":1,"retMsg":"Success","data":[{" ...

  3. 一步一步跟我学DeviceOne开发 - 仿微信应用(一,二,三)

    这是一个系列的文档,长期目标是利用DeviceOne开发一些目前使用广泛的优质手机应用,我们会最大化的实现这些应用的每一个功能和细节,不只停留在简单的UI模仿和Demo阶段,而是一个基本可以使用的实际 ...

  4. 【吉光片羽】之 Web API

    1.在asp项目中直接添加apiController,需要新增Global.asax文件.再增加一个webapiConfig,如果需要访问方式为"api/{controller}/{acti ...

  5. Linux tr命令

    介绍 tr命令可以对来自标准输入的字符进行替换.压缩和删除.tr只能接收来自标准的输入流,不能接收参数. 语法 tr [OPTION]... SET1 [SET2] 注意:SET2是可选项 OPTIO ...

  6. vim添加或删除多行注释

    一.多行注释的添加 1. vim的命令模式下(ESC 进入命令模式): 2. 按CTRL+V进入可视化模式(VISUAL BLOCK): 注意:vim命令模式下v进入的是visual模式,ctrl+v ...

  7. JS设置cookie、读取cookie、删除cookie

    JS设置cookie.读取cookie.删除cookie       JS设置cookie,注意一定要path=/ ,根目录,不然其他目录可能查询不到..默认是本目录. document.cookie ...

  8. angularjs学习曲线

    angularjs学习曲线 刚开始学Augular觉得开发应用需要有相当的编程基础. 不得不说这确实是一款了不起的开发框架,它要求开发人员设计低耦合和可维护的应用. 使用AngularJS 的复杂度就 ...

  9. C# string.format、string.connect和+=运算 效率计算

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Stri ...

  10. 建站集成软件包 XAMPP搭建后台系统与微信小程序开发

    下载安装XAMPP软件,运行Apache和MySQL 查看项目文件放在哪个位置可以正常运行 然后访问localhost即可 下载weiphp官网的weiapp(专为微信小程序开发使用)放在htdocs ...