输入项目名称和路径
然后一直下一步就行了,这就是Qml项目的项目结构,只用看有
锤子图标
的demoQmlApp部分里的main.qml,Source Files是装C++文件的,先不用看
打开main.qml,可以先把这里删了
输入以下内容,然后点击左下角的
绿色三角箭头
运行,你就得到了第一个由qml创建的页面了
Window{
width: 800
height: 400
visible: true
Window组件
写qml就像再写css一样,但是里面又有js的写法,所以编写qml非常的方便和快捷
如果我们需要一个窗口,就需要用到Window组件
基本的属性
通过onWidthChanged
这个去举例,引出槽函数,然后在里面打印它存在的变量,运行后,拉伸窗口宽度,可以看到打印了qml: width: 600
类似的输出
onWidthChanged: {
console.log("width:", width)
Rectangle组件
Rectangle
是用Item
组件引申出来的组件,Item
组件有的,它都有
其实了解了窗口的属性,其他的属性也都是差不多的,id
是为了方便获取组件中的属性值
Rectangle{
id:rect//每个组件都可以有id,但是不能重复
x:120
y:120
color: "#545454"
width: 100
height: 50
z
属性就如css
中的z-index
一样
//常用组件,相当于Widget,继承Item
Rectangle{
x:100
y:100
z:1//调整层数,越大越优先
//而越下面创建的组件,显示层数越高,但是默认z都是1
color: "#131313"
width: 100
height: 50
锚点定位[anchors]
一般是这种形式
anchors.属性: 组件/组件属性/数值
fill 填充完父组件
Rectangle{
//这个就是将这个组件填充满父组件
anchors.fill: parent
color: "#131313"
left/top/right/bottom 锚点定位
让rect2
放在里rect1
方块的右边,并且在同一条水平线,且离rect1距离20
Rectangle{
id:rect1
x:100
y:200
width: 80
height: 40
color: "#131313"
Rectangle{
id:rect2
width: 80
height: 40
anchors.left: rect1.right//放在rect1的右边
anchors.top: rect1.top//与rect1的top对齐
anchors.leftMargin: 20//其实就是相对于当前组件,左边+20而已
color: "#131313"
后面加个Margin
代表该Rectangle
外边距
三种,水平居中,垂直居中,水平垂直居中
Rectangle{
height: 50
width: 50
anchors.centerIn: parent//相对于父组件的中间位置
color: "#434321"
Rectangle{
height: 50
width: 50
anchors.horizontalCenter: parent.horizontalCenter//相对于父组件的水平中间位置
color: "#434321"
Rectangle{
height: 50
width: 50
anchors.verticalCenter: parent.verticalCenter//相对于父组件的垂直中间位置
color: "#434321"
旋转与缩放
通过添加rotation
和scale
属性来旋转和缩放
Rectangle{
width: 80
height: 40
y:250
color: "#325314"
rotation: 60//旋转度数*
scale:1.5//缩放倍数*
Item与Rectangle
而相比于Item,Rectangle多了以下属性
Rectangle{
width: 80
height: 40
x:200
y:300
//多的属性
antialiasing: true//抗锯齿,默认true
border.color: "#847203"//边框颜色
border.width: 3//边框粗细
color: "#691274"//背景颜色
radius: 10//圆角
//gradient: 详细看下一个组件
Rectangle{
width: 80
height: 40
x:300
y:300
gradient: Gradient{//渐变,从上到下
GradientStop{position: 0.0;color: "#634543"}//起点及颜色
GradientStop{position: 1.0;color: "#217342"}//终点及颜色
在qml
中,我们可以通过引入QtQuick.Controls
去使用Button
组件
以下创建了两个按钮,按键盘的左右方向键可以切换这两个按钮的样式
Button{
id:btn1 //访问这个组件,用他的id就行了
objectName: "btn1ON"//不设置也行,在获取按钮名可能就会出现组件名(地址)的情况
width: 80
height: 40
x:100
focus:true
//设置背景,包括边框
background: Rectangle{
//输入btn1.什么,可以获取按钮状态,然后使用三重表达式去切换颜色
color: btn1.focus ? "#131313" : "#f1f1f1"
border.color: "#888"
onClicked: {
console.log("按钮1")
//这里的按键事件,必须要按钮处于聚焦才能触发
Keys.onRightPressed: {
btn2.focus = true
Button{
id:btn2
objectName: "btn2ON"
width: 80
height: 40
x:200
focus:false
background: Rectangle{
//灵活应用可以设置多种触发改变按钮的样式
color: btn2.focus ? "#131313" : btn2.hovered ? "#888" : "#f1f1f1"
border.color: "#888"
onClicked: {
console.log("按钮2")
Keys.onLeftPressed: {
btn1.focus = true
获取正在被聚焦的组件,及信息
onActiveFocusItemChanged: {
//记得设置ObjectName,不然只会出现组件名(地址),可以通过activeFocusItem获取objectName
console.log("当前活动Item:",activeFocusItem,"objectName:",activeFocusItem.objectName)
MouseArea
这个组件为了能让Rectangle等没有点击事件的组件设计而成
主要的方法如下
怎么区分是哪个按键
可以通过按键事件的方法中的一个属性pressedButtons
,来获取当前按下的按键的值,但是这个值不是普通的值,所有要判断,就需要通过pressedButtons == Qt.什么什么
来判断
onPressed: {
console.log(pressedButtons == Qt.LeftButton)
至于为什么在onClicked
中的pressedButtons
值是0
的问题,因为只有按钮按下的才会出现这个值,当松开后,按下的按键的值就会清零
通过PropertyAnimation
可以创建一个属性的动画,并且能够绑定在某个或多个组件中
而PropertyAnimation
需要以下属性,*
为必要
当引用动画的id,可以设置动画的开始和暂停
其实除了PropertyAnimation
外,还有NumberAnimation
、ColorAnimation
,ColorAnimation
就少了properties属性,因为他只用设置颜色数值就行了,而NumberAnimation
只能设置数值属性的动画,例如:
Rectangle{
id:block
width: 75
height: 75
color: "#131313"
// 数值动画,给数值属性添加动画
NumberAnimation{
id:opacityshade
target: block
properties: "opacity"
from: 0
duration: 1000
MouseArea{
anchors.fill: parent
onClicked: {
opacityshade.start()
自动触发动画
只要在PropertyAnimation
或[NumberAnimation
或ColorAnimation
]后面加on 属性
就行了
Rectangle{
id:block1
width: 75
height: 75
y:100
color: "black"
PropertyAnimation on x {
to: 100
duration: 1000
PropertyAnimation on width {
to:150
通过SequentialAnimation
可以创建出队列动画
Rectangle{
id:block2
width: 75
height:75
y:200
color:"black"
//SequentialAnimation也可以跟第二种一样直接执行
SequentialAnimation{
id:toRedThenMoveX100
PropertyAnimation{
target:block2
properties: "color"
to:"darkRed"
PropertyAnimation{
target:block2
properties: "x"
to:100
MouseArea{
anchors.fill: parent
onClicked: {
toRedThenMoveX100.start()
states动画
states
可以设置当前组件的属性多个状态,可以改变这个state
的值来设置不同的状态,PropertyChanges
记得绑定组件id
然后通过按钮事件去更改state
的值,让组件处于其他state
Rectangle{
id: block3
width: 75
height: 75
x: 200
color: "#131313"
state: "block3Released"
states: [
State {
name: "block3Pressed"
PropertyChanges {
target: block3
color: "#666"
State {
name: "block3Released"
PropertyChanges {
target: block3
color: "#131313"
MouseArea{
anchors.fill: parent
onPressed: block3.state = "block3Pressed"
onReleased: block3.state = "block3Released"
然后在组件内通过transitions
属性和Transition
组件来创建动画,我在动画中使用了两种不同的动画创建方法,都一样的,在Transition中,要设置好to属性,from可以省略,默认当前状态
transitions: [
Transition {
from: "block3Pressed"//设置从什么状态
to: "block3Released"//到什么状态的动画
ColorAnimation{
target: block3
Transition {
to: "block3Pressed"
PropertyAnimation{
target: block3
properties: "color"
duration: 1000
就是设置一个只要这个属性改变,就会有动画
形式就是Behavior on 属性{}
如果想引用已经设置好的行为动画可通过animation: 动画id
来设置
以下代码就是方块x或y坐标改变,会有弹性的动画:
Rectangle{
id: block5
width: 75
height: 75
x: 300
y:100
color: "#131313"
//可以在里面设置动画
Behavior on x{
PropertyAnimation{
id:bounce
easing{//设计动画曲线
type: Easing.OutElastic
amplitude: 1
period: 0.5
//也可以应用外面的动画
Behavior on y{
animation: bounce
//只有x或y改变,就会有相应的动画
MouseArea{
anchors.fill: parent
onClicked: {
block5.x += 10
block5.y += 10
Component和Loader
对于用Component包裹的组件,他不会立即将该组件生成到窗口
Component{
id:comp1
Rectangle{
width: 100
height: 100
y:100
color: "#131313"
而要将Component里的组件显示出来需要Loader组件
Loader{
id:loader1 //Loader也可以有id
asynchronous: true //是否异步加载
sourceComponent: comp1
可以通过事件,改变Loader组件加载的Component
onClicked: {
//当把sourceComponent设为空,及不加载任何组件
// loader1.sourceComponent = null
如果用Loader的id去修改Component内的值,则需要通过loader1.item.属性
设置
onClicked: {
//因为当我们把sourceComponent设置为空后,组件销毁,系统就会找不到这个组件
//但是loader中的item可以获取loader中的组件,所有可以用item设置loader加载组件的属性值
// loader1.com1.height = 50//这个不行,可以自己尝试下
loader1.item.height = 50
通过Image组件可以将资源里的图片文件加载出来,source就是资源的目标地址
如果图片的宽高都设置的话,可能会出现变形
Image {
id: img1
x: 200
//加载图片可以通过source
source: "oak.png"
//可设置图片宽高,但是会变形
width: 200
height: 100
如果通过Image加载动图,那图片是不会动的,可以通过组件来加载动图,而且可以设置动图的一下状态
AnimatedImage{
id:img2
x:200
source: "test.gif"
playing: true //是否播放
paused: false //是否停止
speed: 2 //动图加速
Button{
width: 80
height: 40
x:parent.width-80
onClicked: {
img2.playing = !img2.playing //切换动图的播放和停止