Qt Quick应用开发介绍
Introduction to Application Development with Qt Quick Release 1.0
Chapter1 Introduction 介绍
1.1 谁应该阅读这份教程
本教程解释了Qt Quick应用开发的基础以及使用示例代码帮助全面了解; 教程包含标准Qt Quick文档和基础概念, API以及详细的源码信息;
本教程是为了新接触Qt Quick的你准备的, 虽然从基础开始, 但你还是要熟悉编程的概念, 有JavaScript的基础知识更好;
结束本教程之后, 你应该可以写自己的Qt Quick应用, 通过阅读高级文档和分析源码来开始发掘更多的知识;
1.2 journey旅程的目的
本教程会从传统的"Hello World"应用开始, 到一个完整的QtQuick应用结束; 最后的应用程序会覆盖QtQuick编程的各个主要方面;
特性总是会更多的
不要怀疑, 更多的特性会被不断加入, 但是教程不得不在某个有限的程度上结束; 你可以继续了解源码, 扩展程序;
教程就像一个到各个概念点的旅途; 在著名的站点我们会驻足游览, 获得的知识越多, 扩展的方面就越多; 每一步我们都会看些例子, 讨论发生了什么, 如何在我们的应用中使用这些概念; 最后, 你会惊讶程序比起教程的长度来说要简单的多; 我们在这想要的不是快速开发, 而是对整个旅程的充分感受;
在"Hello World"之后, 我们会去开发一些简单应用, 看看怀旧的LED钟; 下一步是在线读取, 分析, 显式天气预报; 迟些, 我们会尝试把这两个应用整合到一起: 一个有LED钟显式的天气预报;
注意, 为了简化, 一些高级的部分在这个教程中没有涉及; 下一章会提到这些;
1.3 下载
http://qt-project.org/wiki/developer-guides 略
1.4 帮助
Qt Bug Tracker
1.5 相关资料
查询Qt网站Document和Wiki;
1.6 License
Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). All rights reserved
http://creativecommons.org/licenses/by-sa/2.5/legalcode
---1---
Chapter2 Work Environmeny Setup 工作环境设置
如果这是你第一个QtQuick项目, 看一下这些工具还是有意义的;
2.1 工具安装
建议使用最新的Qt库; www.qt-project.org/downloads 如果已经有了Qt开发环境, 保证使用版本是Qt4.7.4或4.8包含QtQuick1.1;
2.2 创建QtQuick应用
这个教程中会使用QtCreator作为IDE; http://doc-snapshot.qt-project.org/
QtCreator创建工程的时候只是创建了工程文件[pro], 同时会少许初始化的代码; wizard中关于QtQuick有两个选择: QtQuick App和QtQuick UI; 它们的主要区别在于程序代码是如何执行的, 这和QtQuick在底层是怎样工作的有关;
QtQuick UI: 你会得到一个qml文件和两个项目文件; .qml文件是代码; .qmlproject文件是项目, 现在不用改动; .qmlproject.user是项目设置, 自动生成, 不用改, 也不用放到VCS(版本控制系统)中;
Ctrl-R执行, 或者 Build->Run; 你会看到在一个窗口上的Hello World的text;
Note 这里没有编译步骤, QtQuick是基于脚本的, 就像Python, Perl; 脚本需要有个引擎来解释和执行; QtQuick的引擎叫Qt Declarative UI Runtime http://qt-project.org/doc/qt-4.8/qmlruntime.html [QDeclarativeEngine, QDeclarativeComponent, QDeclarativeContext]
QtQuick程序可以通过两种方式使用引擎:
a) 把qml文件当作命令行选项传给引擎程序: qmlviewer; http://qt-project.org/doc/qt-4.8/qmlviewer.html [QtObject, , runtime.isActiveWindow/orientation]
b) 把Qt Declarative UI Runtiime整合到C++代码, 然后装载qml文件;
用a)方式, 会使用Qt安装路径bin文件夹下的qmlviewer程序; 它包含了使用Qt Declarative UI Runtime的代码, 在命令行装载qml文件; 在QtQuick UI项目中, QtCreator自动运行qmlviewer来装载main.qml, 使用Ctrl-R或者Run来运行; 不需要编译;
qmlviewer程序也提供了debugging接口和许多方便的工具; 看一下文档或者试试 qmlviewer --help;
这种项目类型便于查看QtQuick的效果; 下一节我们会开始学习QtQuick Application项目类型, 理解怎样在C++中开发标准Qt application;
Qt Quick UI只适用于qml文件, 使用script-based程序环境; 复杂程序逻辑和重量级的处理应该放在C++, 然后把API暴露给QtQuick;
2.3 Qt Quick Application 项目类型
另一个项目类型称为Qt Quick Application, 解放所有QtQuick的功能; 如果你创建了一个项目: hello_qt_quick_app, 你会在C++项目中得到:
- hello_qt_quick_app*.png和.svg: 不同平台下的桌面图标;
- hello_qt_quick_app*.desktop: 不同平台的桌面描述文件;
- hello_qt_quick_app.pro: Qt项目
- hello_qt_quick_app.pro.user: 本地项目设置, 自动生成;
- main.cpp: 程序main文件, 用来启动你自己用QmlApplicationViewer实现的qmlviewer;
- qml: 放qml文件的文件夹;
- qmlapplicationviewer: 实现QmlApplicationViewer和初始化Qt Declarative UI Runtime的文件夹, main.qml也在这;
你的程序有了自己的qmlviewer模块, 还有Hello World qml; 这是一个Qt C++程序, 提供了基本的qmlviewer和一些非桌面平台的代码; 如果你运行项目, QtCreator会编译和构建程序, 然后运行; QmlApplicationViewer装载和执行QtQuick的代码, 和qmlviewer的方式一样;
QmlApplicationViewer是一个Qt Declarative UI Runtime的实例; 使用这种方法, 有利于将QtQuick和C++整合起来, 还可以用C++创建一个QtQuick的Item; 相对这篇教程, 这是比较高级的技术; 可以阅读Qt Declarative UI Runtime的文档, 还有Extending QML Functionality using C++ http://qt-project.org/doc/qt-4.8/qml-extending.html
2.4 Tracing跟踪
在学习过程中你可能想要跟踪程序代码, 在运行时进行检查; Debugging特性丰富的, 在Debugging QtQuick Projects中文档齐全 http://qt-project.org/doc/qtcreator-2.6/creator-debugging-qml.html; 第一次使用先要设置好Debugging Helpers http://qt-project.org/doc/qtcreator-2.6/creator-debugging-helpers.html
第一步, 你更多地会使用简单的方式; 可以使用console.log()/debug() 或者直接print(), 这些方法由JavaScript提供;
e.g. mouse click:
1
2
3
4
5
6
7
8
|
MouseArea
{ //... onClicked:
{ console.log( "I
was \"" +
parent + "\"!" ) console.log( "Bye
for now!" ) //... } } |
这块代码会打印出日志信息;
下一步
你现在有了开发环境和简单的Hello World项目, 可以控制, 运行和观察; 下一张继续讨论核心概念, 然后试着做难一点的东西;
---2---
Chapter3 Qt Quick Core Pronciples for Application Development 开发核心原理
3.1 QtQuick和Classical传统Qt比较
作为Qt的一部分, QtQuick(Qt User Interface Creation Kit)提供了一个全新的创建UI和开发的方式; 多数情况下QtQuick被使用在non-widget的UI中, 具有丰富的动画, 效果和图形资源; 它把虚拟转化一个图形元素成为一个可交互的UI component的工作量大大减轻;
你可以将草稿很快做成一个prototype; 甚至从草稿代码到继续开发阶段不用重写代码; 可以把图形, 交互和动画设计都包含进开发过程中, 而不用去画PPT或准备PDF的设计图;
QtQuick的开发不需要C++知识; 它是一个脚本语言, 借鉴于CSS和JavaScript; 语法和功能上用了很多JavaScript的; 它使用JavaScript引擎执行代码; 熟悉QtScript的人会觉得很简单; 虽然不需要C++来开发QtQuick, 但是你可以使用C++扩展QtQuick, 创建自己的模块; 它还可以用来传递数据;
QtQuick不会代替传统Qt
虽然你可以完全只使用QtQuick来开发应用, 传统Qt和C++的角色转换了, 但并不代表不重要了; 在复杂的现实世界程序中, QtQuick主要是给UI和用户交互用的, 程序的业务逻辑和系统接口仍旧是用C++写的;
3.2 Declarative vs imperative programming
QtQuick可以看作是声明式编程 http://en.wikipedia.org/wiki/Declarative_programming的一种实现; QtQuick程序描述了UI是由哪些item组成, 它们看起来应该是怎样的, 应该对用户行为有怎样的相应; 这和传统的Qt C++的命令式编程 http://en.wikipedia.org/wiki/Imperative_programming 有很大区别, 它把算法和语句都放在了前端;
这个区别是为什么QtQuick可以直接用来设计UI的主要原因; UI设计和屏幕内容以及用户交互打交道, 假设程序逻辑是在看不到的地方; 需要的话, QtQuick允许使用命令式编程的元素, 你甚至可以用JavaScript写相当复杂的算法;
3.3 四个cornerstone基石
QtQuickk有4个基础
1) UI由嵌套的元素组合, 排列成一个分层次的树形结构;
2) 元素由属性来描述;
3) 一个属性可以绑定到另一个属性上, 两者一直保持相同的值;
4) 每个属性的改变或信号的发送, 会形成一个通知或者被handler处理;
嵌套地一个个增加元素来写一个QtQuick程序, 自定义元素的外观和行为可以通过改变属性来做到; 如果一个元素的属性要跟随另一个元素的属性的值的变化, 可以绑定它们; 如果你要对属性的改变做出反应, 可以添加一些handler代码来自动执行操作;
1
|
onHeightChanged:
print ( "new
size: " ,
width, "x" ,
height) |
如果你改变窗口的高度, 控制台会输出尺寸信息;
如果这是在传统的text赋值中, 是不会有这种改变, 而且text会保持原始的值; 这是一个很有用的技术, 在QtQuick中会频繁出现;
考虑第四点: 每次属性的改变都会形成一个通知; 我们添加了handler: onHeightChanged; 每次height变化的时候, 就会有log打印到console; 当你想通知其他元素的时候, 还可以发送信号; 一般来说, 第四个基石和传统Qt的属性机制和信号-槽机制类似;
3.4 从概念到实际的程序
概念学习阶段对于QtQuick的程序开发是重要的; UI基于元素, 多数是Rectangle或者类似的东西; 你可以使用属性绑定到通知handler, 实现一个功能系统; 有一个简单的方法来重用和模块化这些功能; 你程序的第一个版本会很快完成, 甚至没有很多应用逻辑; 你可以添加更多应用逻辑, 然后会发现有些东西需要在UI设计上加强; 这种转化在各种平台各种开发框架中都会出现; QtQuick会使得这些转变省下更多时间, 而且更不易错(error-prone) 你只需在开始的时候在设计概念的分解上花点功夫;
接下去开发一个整合天气预报的数字钟; 这个用例程序不仅是装饰类的; 想象一下午夜醒来想要快速查看时间然后继续睡; 如果是在一天的开始, 你有可能想要看看天气预报; 我们的程序显示当前时间和网上抓取的第二天的天气预报; 另外, 我们需要顶层窗口来存储一些基本设置(e.g. 所在城市) 这样就有三个组件: 时钟, 天气预报和设置; 时钟和预报在同一个屏幕, 而设置则是可以弹出和关闭的;
时钟元素看起来像这样:
这个界面显示当前时间和日期, 可以在元素上直接看到;
天气预报通常显示当天信息和之后几天的预报; 这个信息每天都会重复, 显示天气状况和温度; 我们可以从网络上的到天气数据; 天气元素要和天气数据关联起来, 在选择element的时候要记得这点;
根元素包含所有天气相关的元素:
时钟和天气部分相对独立, 而且分开开发然后最后组合到完整的程序中的做法也比较好;
设置会作为一个独立窗口弹出:
这个元素可以独立开发; 只需要注意找到传递配置数据和设置到程序核心的方式;
另外, 还需要一些基本的UI特性, 如text input field, check box, 简单的button; Visual外观很重要, 我们会花更多时间来拓展学习用QtQuick强化程序;
下一步
下一章使用QtQuick elements组建UI;
---3---
Chapter 4 Elements as building blocks 元素作为构建基本块
QtQuick程序可以被看作一个分层的树形元素; 这个树在屏幕的动态场景中组建; 所有元素可以被看作对象, 其中的父子关系也可以看作一种继承; 一些元素在屏幕上不可见, 但是仍然可以在底层控制或转化成其他元素; 因此, QtQuick创建的块都有个通用名字: Item; Item是大多数其他item的父类(QtQuick中有21个); 作为父类, QMLItem有许多重要的属性会被其他item继承; 查看一下文档, 我们大多数时候都会用到这些item, 但是我们只有在强调一个item是屏幕上可见的时候才使用element;
可视化的元素可以通过改变属性(如position, size, visiblity, opacity, etc)来控制; 这也可以通过动画animation来做到; 有一些特殊的element可以用来捕获各处的用户输入或者可视化的数据; Qt文档提供了一个group列表: http://qt-project.org/doc/qt-4.8/qml-groups.html
开发QtQuick的时候, 你应该以element为单元考虑UI; UI的变化是transition, element可以移动, 隐藏甚至改变形状; 这和传统编程很不同, 以前思考的是算法, 花不少的时间来让UI变化; 用QtQuick开发UI更像是在做动画;
4.1 用nested嵌套element来Compose组合一个基本UI
在qml中, 就像其他树形结构, 总是有一个根元素, 包含所有其他的元素;
1
2
3
4
5
6
7
8
9
|
Rectangle
{ width:
360 height:
360 Text
{ anchors.centerIn:
parent text: "Hello
World! My size is " + parent.width
+ "
x " +
parent.height + "!" } //... |
Rectangle是根元素; Text包含文字; 所有的item当作在一个栈上渲染(render), render次序按照它们在树中次序的排列;
根Rectangle 2.Text...
我们可以添加更多element, 所有都会加在这个栈中, 从左上端(0,0)开始画出; 这是默认的render位置; 这个默认行为会让例子中的元素重叠在屏幕上; 可以添加anchors来指定位置; 锚(anchoring)允许element按照互相之间的相对关系来调整位置;
4.2 在屏幕上order排列element
你可以通过绝对位置(x,y)或者相对位置来控制元素位置或者排列顺序;
坐标系统从窗口左上角开始, 以真实的像素为单位; 除了(x,y)坐标系, item还有第三个维度, 定义了兄弟item的堆叠顺序; 这个维度用z属性来定义, 默认值是0; 如果你把z设置为1, item会升到下一个层次;
ordered_elements/ordered_elements.qml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
Rectangle
{ width:
100 height:
100 color: "grey" Rectangle
{ width:
50 height:
80 color: "lightgrey" //
puts this rect in the front. //
Uncomment next line or set it to -1 and see what happens //z:
1 //
this rect will clip the text element //
Uncomment this line and see what happens //
clip: true Text
{ text: "Sunday,
5 o’clock" } } } |
把z设置为-1会把item隐藏进父类的背景中;
Note 如果不把修剪clip属性设置为true, text会在父类的边界处被clip掉; clip是Item的属性, 在所有可视化的element中被继承;
4.3 Arrange整理屏幕上的程序元素element
下一步要整理element, 构筑UI; 整理item带出下一个关键点: item的id;
虽然id在QtQuick中是可选的, 但我们在整理item关系的时候一定会用到它; 通常, 你应该考虑尽量把所有的id都加上; 这样大大提高代码的阅读性, 还可以防止奇怪的副作用; 建议对根元素使用一致的id, 比如root; 这可以帮助你跟踪item的使用情况, 并且防止副作用产生;
前面的例子里用到了anchors, 现在仔细瞧瞧它怎样搭出一个时钟;
拿两个Text元素放入root元素; anchors行使用起来就像属性一样, 把anchors行的属性绑定到另一个上; 基本操作就是把一个anchors属性连到另一个上面; 另外, 你还可以设置anchors留白(margin); margin默认是0, 它定义了设置了anchors的items之间的距离;
1
2
3
|
anchors.bottom:
root.top anchors.horizontalCenter:
parent.horizontalCenter anchors.margins:
10 |
我们把timeText连到root的top, margin设置为10像素; dataText设置到root的bottom; 当你运行程序然后调整窗口大小时, 你会看到Text会保持anchors的位置, 留在top或者bottom处, 只是它们之间的空间大小会变化;
1
2
3
4
5
6
|
MouseArea
{ anchors.fill:
root onClicked:
{ Qt.quit(); } } |
MouseArea填充了整个root的表面, 甚至鼠标点击Text的时候也会响应;
Anchors很简单, 但是如果你有很多element的时候还是要注意, 否则你可能丢失element位置方向; 一个有用的方法是anchor到主元素, 然后保证anchor的层次顺序; Detail: http://qt-project.org/doc/qt-4.8/qml-anchor-layout.html
另一种方式是Positioner: http://qt-project.org/doc/qt-4.8/qml-positioners.html 用来处理一些按常规次序排列的element; [Row, Column, Flow...]
ex. 可以试着使用positioner, 它可以简化代码, 将两个Text放到Column中; spacing是间距, anchors.centerIn: root可以保持Column在root的中间;
static_clock1/static_clock1.qml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
Column
{ id:
clockText anchors.centerIn:
root spacing:
20 Text
{ id:
timeText anchors.horizontalCenter:
parent.horizontalCenter text: "13:45" } Text
{ id:
dateText anchors.horizontalCenter:
parent.horizontalCenter text: "23.02.2012" } } |
如果你调整窗口大小, 内容会保持在中间;
4.4 Properties属性
前面一节中我们把各种值绑定或分配给了property, 从而改变Item; property扮演了重要角色, 而且有广泛的使用; 这节制讨论用户案例然后做练习;
1
2
3
4
|
Rectangle
{ id:
myButton color: "white" } |
myButton自动包含了所有Rectangle的默认属性, 包括默认值; 实现一个button, 你可能需要添加一些属性, e.g. border color 甚至是一个普通的pen来画label text和border color; 根据应用逻辑来实现其他的item;
根据下面的语法来定义新的属性:
1
|
[ default ]
property <type> <name>[: defaultValue] |
比如一个border color:
1
|
property
string borderColor: "white" |
这里使用了string类型; QML property的基本类型: http://qt-project.org/doc/qt-4.8/qdeclarativebasictypes.html : action, enumeration, list..
有些情况下, 定义一个别名alias可以代替定义新的属性;
1
|
[ default ]
property alias <name>: <alias reference> |
实际上, 在这个例子中, button继承自Rectangle, 我们应该定义一个别名, 因为Rectangle已经有个property来定义border color;
1
2
3
4
|
Rectangle
{ id:
myButton property
alias borderColor: myButton.border.color ... |
default关键字是可选的, 用来创建默认属性; 更多进级用法: http://qt-project.org/doc/qt-4.8/qml-extending.html#default-property & http://qt-project.org/doc/qt-4.8/propertybinding.html#default-properties
就如前面提到的, 一个property的改变产生notification信号, 会有一个handler来相应property change; handler被分配到属性的 on<property_name>Changed方法, 这些方法是property自动生成的, 包括自定义的property;
ex: Rectangle的width和height
1
2
|
onWidthChanged:
console.log( "Rectangle
width: " ,
width) onHeightChanged:
console.log( "Rectangle
height: " ,
height) |
如果你resize这个窗口, 你会看到console的输出: width的height的改变;
handler中的代码可以变得更繁复, 可以使用JavaScript;
property绑定是另一个基础; 它可以使一个property跟随另一个property的改变而改变; 这可以发生在不同的item中, 而且实际上大多数时候是用在不同的item之间的; 绑定发生在每次你使用冒号 : 的时候, 右边的值是可变的;
1
2
|
id1.text:
id2.text //
text in the id1 follows changes of the text in id2 width:
16 height/9 //
this keeps an item being the 16:9 aspect ratio :-) |
你也可以做些计算甚至将一个有返回值的function绑定上去;
property_binding/property_binding.qml
鼠标点击事件被MouseArea接收, 在onClicked hander中可以通过JavaScript进行处理;
1
2
3
|
property
int adaptiveSize: root.width/10 ... font.pixelSize:
adaptiveSize |
如果resize窗口, font的像素尺寸将会根据root的width/10来变化;
4.5 Other Visual Composition Elements 其他可视化的组合元素
QtQuick1.x提供了宽泛的item选择来创建UI: http://qt-project.org/doc/qt-4.8/qdeclarativeelements.html 其中有4个element能用来组建UI;
- 可视化的element, 如text, rectangle;
- 加载的Loaded内容如image, web page, font;
- 可视化的element, 用各种方式来整理上面元素, 需要的话可以使用带数据的model;
- 效果effect, 比如动画animation和过渡transition;
Qt5增加了两个:
- 矢量图形画布
- 3D渲染OpenGL效果effect和着色shader;
refer to http://qt-project.org/wiki/Developer-Guides/
即使你还没有在列表中看到高级的UI compontent, QtQuick给了你足够多的能力来组合丰富的UI; 这些UI可以像卡通, 图像接收用户输入, 平滑地改变形状, rectangle变成circle, ellipse等等; 你也可以轻松创建经典的UI components; 当你开始做UI的时候, 试着先分解成基础元素, text, image, view; 想想element互相之间是怎么交互的, 用户输入和变化时会发生什么;
下一步
下一章学习怎样加载外部内容, 创建所需的UI样式;
---4---
Chapter5 Loading and Displaying Content 加载和显示内容
加一步要在时钟上加上背景图代替实色solid color, 用不同字体显示时间和日期; 这个内容的样式通常是在外部文件中提供的; 我们不得不学习怎样读取和现实这样的内容; 也要学习怎样自定义元素的标准外观, 来将一个应用的外观实现得更有吸引力;
5.1 Access and load content 访问和读取内容
QtQuick 1.x允许在网络上或者本地文件系统中加载image和font; 可读取内容的相关文件的路径根据QML文件的相对位置来定义; 这相对路径也可以被网络地址代替; 这样把内容从本地移动到网络上就很简单, 不需要代码有很大的改变; detail: http://qt-project.org/doc/qt-4.8/qdeclarativenetwork.html
读取外部内容可能总是会出问题; 文件方错了, 网络连接太慢或者服务器下线了; Image和FontLoader 提供了status和progress属性来处理这些情况; progress的值从0.0到1.0变化, 和真实的读取进度保持一致; 如果内容是从文件系统读取的, 而我们没有在程序中使用它, 进度会几乎立即被设为1.0; 读取字体的代码块code segment, 以及跟踪的状态如下:
1
2
3
4
5
6
|
FontLoader
{ id:
ledFont source: "./content/resources/font/LED_REAL.TTF" onStatusChanged: if (ledFont.status
== FontLoader.Error) console.log
( "Font
\"" +
source + "\"
cannot be loaded" ) } |
我们的新font, LED_REAL.TTF, 保存在content文件夹, 和程序在相同的位置; 如果由于某些原因无法加载, console会打印出错误信息, 程序会继续使用默认font;
5.2 Basic Image Parameters 基本的图像参数
加载Image的方式和Font一样:
1
2
3
4
5
6
7
|
Image
{ id:
background source: "./content/resources/light_background.png" fillMode: "Tile" anchors.fill:
parent onStatusChanged: if (background.status
== Image.Error) console.log ( "Background
image \"" +
source + "\"
cannot be loaded" ) } |
这里需要改变一些图像的属性; image要覆盖整个顶层元素(parent)的表面; 很多情况下, 会使用用带图案pattern的小图片填充一个背景; 缩放scale图片的大小让它适应背景尺寸会改变pattern, 背景就会和设想的不一样; 这样的情况下, 你可以设置fillMode为Tile;
处理Image的尺寸
图片的大多数可视化属性可以通过父类(Item)的属性来改变; 其他Image的属性帮助处理关键的Image的样子--size; 如果你要处理大图片, 你应该设置sourceSize, 设置成你真正需要的尺寸, 否则图像将以全尺寸加载; 注意paintedHeight和height的区别, 还有paintedWidth和wdith; painted属性描述了图片在画到屏幕上时占据的区域大小, 而普通的h/w属性描述了图像加载的尺寸; 如果图片被scale过, 这两者的大小可能都不同; 如果你把从Item继承而来的scale属性改变了, 要注意fillMode对真实的scale结果上的影响; smooth属性可以将缩放过的图像边缘平滑, 但是也会引来性能损耗performance cost;
5.3 Basic Text Parameters 基本的文本参数
第一节中我们读取了一个自定义的 LED-like字体; 现在要将它分配给相应的text元素; Text有一组font属性; 它被用来自定义给中字体相关的text属性; 其中font.family持有font的名字;
找到安装的字体
有时要找到你系统中有哪些字体被安装, 它们的名字是什么, 是很麻烦的事情; 这里有个例子: http://qt-project.org/doc/qt-4.8/declarative-text-fonts-fonts-qml-fonts-qml-availablefonts-qml.html
text的其他属性允许text外观上的各种改变; 在我们的例子中, 使用color, style和size相关的属性;
自定义的text元素看起来像这样:
1
2
3
4
5
6
7
8
9
10
|
Text
{ id:
timeText text:
root.currentTime font.pixelSize:
root.height //root.timeTextProportion font.family:
ledFont.name font.bold: true color:
root.textColor style:
Text.Raised styleColor: "black" } |
计划是将实现变得尽量灵活, 对于所有element的size和布局layout在不同的屏幕尺寸上运行都能适应; 因此上面的代码将pixelSize绑定到了root的height上; 这样text会跟随root的height而缩放; 这里还有方法去做得更好, 但是这个版本的QtQuick没有提供font metrics(度量单位)数据; 如果有font metric的话, 我们可以让text的size自适应width的变化 [C++可以通过QFontMetrics做到]
为了让timeText更好看点, 我们用了点小技巧, 把style设置为Text.Raised, styleColor设为"black"; 这让text从背景中分离开, 看起来好像悬浮在上面一样;
Text还提供了基本的布局控制(e.g. 你可以设置wrapMode) 最主要的事情是要记住text的格式, Text支持rich text的修饰; 这使得一块text中的不同部分可以用各种不同的格式来显示, 包括color, size, etc;
5.4 Get ready for translation 翻译
开发程序的时候, 基本都要考虑考虑国际化版本, 即使你暂时还没有计划; Qt提供了一系列根据来给QtQuick使用; 如果你一开始就知道这些必须的工具, 那么在你的代码变多, 程序变成复杂的系统的时候可以帮你节省很多时间;
QtQuick提供的翻译相关的API基本和Qt Script一样; http://qt-project.org/doc/qt-4.8/scripting.html#produce-translations [qsTr(), qsTranslate() and the QT_TR*_NOOP()] 主要的API是qsTr()方法, 应该在程序所有可见的string上都包装这个方法;
ex. hello world
1
2
3
4
|
Text
{ anchors.centerIn:
parent text:
qsTr( "Hello
World" ) } |
程序将和使用qsTr()之前一样允许; 你需要使用Qt translation工具链来让翻译起效; 参考http://qt-project.org/doc/qt-4.8/qdeclarativei18n.html , 了解怎样生成和整合翻译文件; 当翻译文件准备好了, 有3个方式来加载它们:
- 通过使用qmlviewer命令行选项 -translate
- 将文件放到 i18n子目录(http://qt-project.org/doc/qt-4.8/declarative-i18n.html ); [lupdate linguist lrelease]
- 通过改变qmlviewer的默认行为, 用自己的方式来加载QML和翻译文件(超出本文范围)
如果你想要做一个right-to-left的程序版本, e.g. Arabic, 查看 QML Right-to-left 用户接口 http://qt-project.org/doc/qt-4.8/qml-righttoleft.html
运行时切换语言
现在还没有标准的API可以在QtQuick程序开始后加载新的语言; 但还是可以使用一些其他的代码; http://qt-project.org/wiki/How_to_do_dynamic_translation_in_QML/ [利用空字符串emit textChanged消息]
更多关于internationalization的细节:
- Qt文档: http://qt-project.org/doc/qt-4.8/i18n-source-translation.html
- Qt文档: http://qt-project.org/doc/qt-4.8/internationalization.html
- Qt开发者Wiki: http://qt-project.org/wiki/QtInternationalization [tr() 和 toUtf8()]
5.5 Static Clock Application Code 静态的时钟程序代码
static_clock2/static_clock2.qml
下一步
下一章关于QtQuick里的脚本script; 用一个小脚本让时钟走起来;
---5---
---YCR---
Qt Quick应用开发介绍 1-5,布布扣,bubuko.com
原文:http://blog.csdn.net/roymuste/article/details/38636947