Qt_Quick开发实战精解
signal clicked
MouseArea {
anchors.fill: parent
onClicked: {
root.clicked() //传递信号给root
console.log("MouseArea signal")
} //绑定 信号到parent
}
onClicked: {
console.log("Image signal")
}
信号调用函数
onClicked: {
// reset our little scene
circle.x = 84
box.rotation = 0 //旋转
triangle.rotation = 0
triangle.scale = 1.0 //范围
_test_transformed()
}
Column { 把子项放入一列
id: col
anchors.centerIn: parent
spacing: 8
RedSquare { }
GreenSquare { width: 96 }
BlueSquare { }
}
Flow { //将子项并排放置
anchors.fill: parent
anchors.margins: 20
spacing: 20
RedSquare { }
BlueSquare { }
GreenSquare { }
}
Grid {
id: grid
rows: 2 行数
columns: 2 列数
anchors.centerIn: parent
spacing: 8
RedSquare { }
RedSquare { }
RedSquare { }
RedSquare { }
}
创建8行12列矩阵
DarkSquare {
id: container
width: 800
height: 480
property int marginTop: 16 边距
property int marginRight: 32
property int marginBottom: marginTop
property int marginLeft: marginRight
property int columns: 12
property int rows: 8
property int spacing: 12 子项之间的间隔
property int cellWidth: (width-marginLeft-marginRight-(columns-1)*spacing)/columns 每个子项的长宽
property int cellHeight: (height-marginTop-marginBottom-(rows-1)*spacing)/rows
Grid {
anchors.fill: parent
anchors.topMargin: parent.marginTop
anchors.rightMargin: parent.marginRight
anchors.bottomMargin: parent.marginBottom
anchors.leftMargin: parent.marginLeft
spacing: parent.spacing
columns: parent.columns
Repeater {
model: container.columns * container.rows
RedSquare {
width: container.cellWidth
height: container.cellHeight
}
}
生成一个网格矩阵,由16的颜色随机的矩形组成
Grid{ //网格
anchors.fill: parent
anchors.margins: 8 //边距
spacing:4
Repeater {
model: 16
Rectangle {
width: 56; height: 56
property int colorIndex: Math.floor(Math.random()*3) //产生随机下标
color: root.colorArray[colorIndex] 颜色数组
border.color: Qt.lighter(color)
Text {
anchors.centerIn: parent
color: "#f0f0f0"
text: "Cell " + index
}
}
}
Rectangle {
focus:true
捕获方向键
keys.onLeftPressed: keys.onRightPressed keys.onUpPressed keys.onDownPressed
keys.onPressed:{
按键事件:
switch(event.key){
case Qt.key_Plus:
case Qt.key_Minus:
}
}
keys.onPressed:
}
输入框常规属性 TextInput{
id: input
x: 8; x:9
focus: true
text: 'str'
KeyNavigation.tap:(打开导航键Tab) input.id
}
FocusScope { //显式创建焦点范围
width:
height:
TextEdit{
id: input
anchors.fill
anchors.margins:
focus: true
}
}
image : fillmode 填充模式
keyNavigation.tab 导航键
信号: onHightChanged
渐变:
gradient: Gradient {
GradientStop { position: 0.0; color: "lightsteelblue" }
GradientStop { position: 1.0; color: "slategray" }
}
border.color: "slategray"
属性
Text: {
onTextchanged: 信号
focus: bool
Key.onSpacePress:{
function()
}
Key.onEscapePress:
{
Label.text= " "
}
}
button:
Rectangle{
id:root
property alise text: label.text
signal clicked 声明一个信号
border.color:
Text{
id:
anchors.centerIn:
text:
} MouseArea{
anchors.fill:
onClicked:
{
root.cliced()
}
}
}
QML对象管理:
Loader,Repeater,ListView,GridView ,PathView
要动态的加载定义在QML文件中的组件, 可以调用Qt.createComponent()函数
Sprite.qml
import QtQuick 1.0
Rectangle {
width:80
height: 50
color: 'red'
}
import QtQuick 1.0
import 'componentCreation.js' as MyScript
Rectangle
{
}
if (component.status == Component.Ready)
finishCreation()
else
component.statusChanged.connect(finishCreation)
}
function finishCreation(){
if(component.status == Component.Ready)
{
sprite = component.createObject(appWimdow);
if(sprite == null)
{}
else
{
sprite.x = 100
sprite.y =100
}
}
else if (component.status == Component.Error)
{
console.log("Error loading component: ",component.errorString());
}
}
动态创建对象
Sripte.qml
import QtQuick 2.0
Rectangle {
width: 80
height:50
color: "red"
}
xxxx.js
var component
var sprite
对外提供的方法
function createSpriteObjects() {
//创建一个对象
component = Qt.createComponent("Sprite.qml")
if (component.status == Component.Ready)
finishCreation()
else
component.statusChanged.connect(finishCreation)
}
function finishCreation(){
if(component.status == Component.Ready)
{
sprite = component.createObject(appWindow);
if(sprite == null)
{}
else
{
sprite.x = 150
sprite.y =150
}
}
else if (component.status == Component.Error)
{
console.log("Error loading component: ",component.errorString());
}
}
main.qml
import QtQuick 2.0
import "componentCreation.js" as MySript
Rectangle{
id : appWindow
width: 300;height: 300
//调用js方法
Component.onCompleted: MySript.createSpriteObjects();
}
如果qml知道运行时才被定义: 可以使用QtcreateQmlObject()函数创建一个qml对象
var newObject = Qt.createQmlObject(import QtQuick 1.0;Rectangle {color: "red"; width :20;height: 20},parentItem,'dynamicSnippet1')
1 要创建的字符串 2 父对象 3 新对象的文件路径
确保创建上下文不会在创建对象前被销毁,
如果使用了 Qt. createComponent ( ) ,创建上下文就是调用该函数的
QDeclarati veContext;
如果使用了 Qt. createQ mlObjectO .创建上下文就是父对象的上下文;
如果定义了 一 个 Component {} .然后在其上调用了 createObject O. 创建上下文就是该 Component 中定义的上下文.
。不要手动删除通过 QML 元素(例如 Loader和 Repeater) 动态生成的对象,不要删除不是自己动态创建的对象。
创建5个红色矩形,10秒消失
selfDestroy.qml
Rectangle{
id: rect
width:80
height: 80
color: "red"
NumberAnimation on opacity{ 动画应用于透明度
to:0
duration: 10000 持续时间
onRunningChanged: 当动画停止时信号
{
if(!running)
{
console.log("Destory...")
rect.destroy() 调用销毁函数
}
}
}
}
main.qml
Item{
id: container
width: 500
height: 100
Component.onCompleted:{
var component = Qt.createComponent("SelfDestoryRect.qml") 创建一个selfDestroy对象组建
for(var i = 0; i< 5;i++)
{
var object = component.createObject(container) 父对象
object.x = (object.width +10)*i
}
}
}
因为只有动态创建的对象才可以被动态删除.使用 Qt. createQmlObjectO 创建的对象可以相似的使用 destroyO 来删除 :
var newObject = Qt.createQmlObject(import QtQuick 1.0;Rectangle {color: "red";width: 20;height:20},parentItem,"dynamicSnippet1")
静态创建对象:
Item{
SelfDestroyRect{....}
}
QML 的作用域:
JaveScript 的作用域:
QM L 的作用域扩展并没有干扰 JavaScript 本身的作用城.
,在它们任意一个里面声明的局部变母都不会和在另外 一 个里面声明的局部
变量冲突。
绑定的作用域对象:
绑定可以不加限制地访问作用域对象的属性
anchors.left: parent.left
PathView{
delegate:Component
{
Rectangle{
id:root
Image{
要明确限定根元素
scale: root.PathView.scale
}
}
}
}
组件的作用城是 组件内的对象id和组件的根元素的属性的联合,
Item{
property string title
Text{
id: titleElement
text: "<b>"+title+"</b>"
...
}
Text{
text: titleElement.text
...
}
}
组件的实例的层次:
,组件实例将它们的作用域关联在一起形成了 一 个作用域层次.组件实例可以直接访问其祖先的作用域.
Item{
property color defaultColor:"blue"
ListView{
delegate: Component{
Rectangle
{
defaultColor
}
}
}
}
组件实例作用域层次可以扩展到非内联的组件:
Item:
{
property string title: "hello world"
TitleText{
}
TitleText{
}
}
TitleText.qml
Text{
text: "<b>"+title+"</b>" 可以访问到main.qml中的title
}
动态作用域是非常强大的,但是必须谨慎使用以避免 QML 代码的行为变得难
以预料。
QML的国际化:
qsTr() qsTranslate() QT_TR_NOOP()将字符标记为可翻译的
编码约定:
id:
属性声明
信号声明
JaveScript函数
对象属性
子对象
状态
状态切换
分组属性:
anchors {left: parent.left; top: parent.top; right:parent.right;leftMargin:20}
font{bold:true;italic:true;pixelSize:20;capitalization: Font.AllUpperacase }
Item{
id: component
width: 40;height: 50
property real _area: width*geight*0.5 私有属性不为外部使用 两个下划线
}
定位器: Column Row Grid Flow
重复器:Repeater 包含一个模型 model 和 一个委托 delegate 属性 : 委托用来将模型中的每一个条自分别实例化
切换:切换可以使在定位器中进行添加、移入或者删除项目时具有动画效果。
Flow{
id: positioner
move: Transition{
NumberAnimation{
properties: "x,y"
ease: "easeOutBounce"
}
}
}
锚的布局:
left horizontalCenter right top verticalCenter baseline bottom margin offset horizontalCenterOffset verticalCenterOffset baselineOffset
基本可视元素:
Item : Keys属性 visible属性 children属性 resources 属性 opacity属性 z属性(设置兄弟项目的堆叠顺序)
默认data属性可以省略data标签
Item{
可见属性
children: [
Text{},
Rectangle{}
]
不可见属性
resources:[
Timer{}
]
}
定位子项目和坐标映射:
childAt(real x,real y) 返回在(x,y)处的子项目
mapFromItemOtem item , real x , real y) 函数会将Item 坐标系 统中的点以(x, y) 映射到该项目的坐标系统上,返回 一 个包含映射后的 x和 y 属性的对象.如果 Item 被指定为 null 值,那么会从根 QML 视图坐标系统上的点进行映射。对应的还有一个 mapTo1temOtem item , real x , real y) 函数,它与mapFromltemO 是很相似的,只不过是从当前项目坐标系统的 (x , y) 点映射到 item的坐标系统而已
Rectangle: gradient属性radiu属性(弧度).smooth属性(损失渲染性能)
Text: wrapMode属性(设置换行) elide属性(自动省略) 只读文本
FontLoader元素加载字体,FontLoader{id:webFont;source:"http://www.mysite.com/myfont.ttf"}
style属性(文本样式)连接信号 Text::onLinkActivated(strig link)
Text{
textFormat: Text.RichText
text:"The main wensite is at <a href = \"http://www.baidu.com\"> 百度</a>."
onLinkActivated: console.log(Link+"Link activated")
}
TextEdit:focus属性 Flicabe元素 selectByMouse属性
Flickable{
id:flick
width:300;height:200
contentWidth:edit.paintedWidth
contentHeight:edit.paintedHeight
clip:true
function ensureVisible(r) {
if(contentX >= r.x)
contentX = r.x
else if (contentX + width<r.x + r.width)
contentX = r.x+r.width-width
if(contentY>=r.y)
contentY = r.y
else if (contentY + height<r.y+r.width)
contenY = r.y+r.height-height
}
TextEdit{
id: edit
width: flick.width
height: flick.height
focus: true
wrapMode: TextEdit.Wrap
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
}
}
TextEdit 通过:cut() copy() paste() 对剪切版支持
TextInput:单行输入: echoMode
validator: IntValidator{bottom:11;top:30}直到验正IntValidator 来实现在 Textlnput 中只能输入 11-31 之间的整数.