QML基础

从 Qt 4.7 开始,Qt 引入了一种声明式脚本语言,称为 QML(Qt Meta Language 或者 Qt Modeling Language),作为 C++ 语言的一种替代。而 Qt Quick 就是使用 QML 构建的一套类库。 QML 是一种基于 JavaScript 的声明式语言。
 

每一个 QML 有且只有一个根元素,

一个 QML 文档分为 import 和 declaration 两部分。

qml的打印

使用:console.log(打印的字符串,打印的参数)

元素

基础元素

根元素

每一个QML文件都需要一个根元素,并且只能有一个根元素。

window

Opacity---透明度

值在0~1之间

属性改变时会触发对于的属性改变槽函数

 组件中的任何属性(包括自定义属性),都有改变时触发的槽函数

Item

属性和值

对于元素具有哪些属性可以直接查看QT帮助文档,让后进行设置就可以。

属性和属性可以设置的值都是已经定义好的,我们要做的就是知道属性和属性值的设置。

id

在其他元素中可以通过元素的id访问元素的属性

也可以自己使用自己的id访问自己的属性

x和y,z

相对于屏幕左上角

z为正数就靠平面前面

对于一个元素的x,y是在哪个位置

width和heigth

有这两个属性的组件,如果不设置这两属性,组件不显示。

focus

焦点

焦点所在对象就是要控制的对象;

如果对象没有获取焦点,是不能(键盘或者鼠标)被控制的。

锚点(anchor)

设置一个元素或者组件的位置可以设置x,y,z,也可以通过锚点设置。

位置指定

Text {

         text: qsTr("Hello World")

         anchors.centerIn: parent

}

设置元素位置方式

1,x,y,z

2,anchors

rotation--旋转

顺时针旋转

scale---改变大小

width和heigth乘以指定的倍数

rectangle的gredient

设置颜色渐变

rectangle单边框设置

需要设置内外两个rectangle,通过设置margin(边缘)来设置两个rectangle的边缘宽度。

自定义组件:

import QtQuick 2.0

Rectangle{
    id:root
    width: 200
    height: 100

    color: "#ff3300"
    //border.color: "#4c8dae"

    property int m_topMargin: 0
    property int m_bottomMargin: 0
    property int m_leftMargin: 0
    property int m_rightMargin: 0

    Rectangle{
        id: innerRect
        anchors.fill: parent
        color: "#ae7000"

        anchors.topMargin: m_topMargin
        anchors.bottomMargin: m_bottomMargin
        anchors.leftMargin: m_leftMargin
        anchors.rightMargin: m_rightMargin
    }
}

main.qml调用

import QtQuick 2.6
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    x:100
    y:100

    MyRectangle{
        //id:myRect
        x:200
        y:200
//        width: 200
//        height: 100

        m_topMargin: 10
        m_bottomMargin: 10
    }
}

state---states:[ ]

state

属性指定组件当前是使用哪个状态的属性。

states:[ ]

中指定这个组件的多种state(状态);

我们可以在states中设置组件的多种状态,在需要的不同时刻设置组件的state属性为states中的对应状态。

name是状态的名字;

PropertyChanges中可以设置这个状态的属性;

自定义文件中设置属性:

import QtQuick 2.0

Rectangle{
    id:root
    width: 200
    height: 100

    color: "#ff3300"
    //border.color: "#4c8dae"

    property int m_topMargin: 0
    property int m_bottomMargin: 0
    property int m_leftMargin: 0
    property int m_rightMargin: 0

    Rectangle{
        id: innerRect
        anchors.fill: parent
        color: "#ae7000"
        state: "normal"

        anchors.topMargin: m_topMargin
        anchors.bottomMargin: m_bottomMargin
        anchors.leftMargin: m_leftMargin
        anchors.rightMargin: m_rightMargin

        states: [
            State {
                  name: "normal"
                  PropertyChanges {target: innerRect; color:"#ae7000"}
            },
            State {
                  name: "red_color"
                  PropertyChanges { target: innerRect; color: "red" }
            },
            State {
                  name: "blue_color"
                  PropertyChanges { target: innerRect; color: "blue" }
            }
        ]
        MouseArea{
            anchors.fill: parent

            onPressed: {
                innerRect.state="red_color"
            }
            onReleased: {
                innerRect.state="blue_color"
            }
        }
    }

}

动画效果属性

动画有8种类型

propertyAnimation

 PropertyAnimation支持所有属性

sequentialAnimation

可持续多个动画效果

动画效果的两种实现方法

1,将动画效果设置为组件的属性

需要执行动画的时候,动画名.start()就开启属性。

Rectangle {
      id: flashingblob
      width: 75; height: 75
      color: "blue"
      opacity: 1.0

      MouseArea {
          anchors.fill: parent
          onClicked: {
              animateColor.start()
              animateOpacity.start()
          }
      }

      PropertyAnimation {id: animateColor; target: flashingblob; properties: "color"; to: "green"; duration: 100}

      NumberAnimation {
          id: animateOpacity
          target: flashingblob
          properties: "opacity"
          from: 0.99
          to: 1.0
          loops: Animation.Infinite
          easing {type: Easing.OutBack; overshoot: 500}
     }
  }

弊端:

即使是同类型的动画效果也要设置在各自的动画属性中:

2,on某个属性

在需要产生动画的位置直接开启动画

    Rectangle {
          id: rect
          width: 100; height: 100
          color: "red"

          PropertyAnimation on x {
              to: 200;
              duration: 1500
          }
          PropertyAnimation on y {
              to: 100
              duration: 1500
          }
          NumberAnimation on width{
              to:300
              duration: 1500
          }
    }

transitions---states

transitions中指定states中状态变换,并且实现动画效果。

不需要开启transitions中的转变,只要指定的状态发送改变transitions就会自动执行。

Rectangle {
          width: 75; height: 75
          id: button
          state: "RELEASED"

          MouseArea {
              anchors.fill: parent
              onPressed: button.state = "PRESSED"
              onReleased: button.state = "RELEASED"
          }

          states: [
              State {
                  name: "PRESSED"
                  PropertyChanges { target: button; color: "#801dae"}
              },
              State {
                  name: "RELEASED"
                  PropertyChanges { target: button; color: "#dc3023"}
              }
          ]

          transitions: [
              Transition {
                  from: "PRESSED"
                  to: "RELEASED"
                  ColorAnimation { target: button; duration: 1500}
              },
              Transition {
                  from: "RELEASED"
                  to: "PRESSED"
                  ColorAnimation { target: button; duration: 1500}
              }
          ]
      }

property

property可以用来声明所有类型的属性

可以声明基本数据类型,元素,和组件

声明是可以指定属性的值,也可以不用指定,使用到的时候再传参。

requerd property

要求属性必须要有赋值,无论是定义的时候,还是过程中。

property----var

使用var(variable--变量)来声明变量,Qt自动推导类型,不需要设计者关系设计的类型。

property----list<>

声明一个数组--property list<Rectangle>

property定义的属性加上权限

这个属性只能读取,不能改变。 

property alias

别名

可以给组件,或者组件的属性取别名。

 Rectangle背景设置为透明色,而不是白色

自定义属性

添加自己定义的属性需要使用property修饰符,然后跟上类型,名字和可选择的初始化值(property : )。如果没有初始值将会给定一个系统初始值作为初始值。注意如果属性名与已定义的默认属性名不重复,使用default关键字你可以将一个属性定义为默认属性。这在你添加子元素时用得着,如果他们是可视化的元素,子元素会自动的添加默认属性的子类型链表(children property list)

组件---component

为什么需要组件

组件的常用槽函数

onCompleted()

窗口创建的时候触发

onDestruction()

窗口销毁时触发 

component中创建组件是不会被自动创建的

需要Loader加载控件

通过source加载:source+元素路径

 sourceComponent:+组件id

sourceComponent=null时loader加载的组件将被销毁

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    x:100
    y:100

    Component{
        id:m_comp
        Rectangle{
            id:comp_rect
            width:100
            height: 100

            color: "#a98175"
            Component.onCompleted: {
                console.log("create");
            }
            Component.onDestruction: {
                console.log("destructed");
            }
        }
    }
    Loader{
        id:loader
        //source: "/MyRectangle.qml"
        sourceComponent: m_comp
        onStatusChanged: {
            console.log("loader status:",status);
        }
    }

    Button{
        id:button
        x:300
        y:300
        width:100
        height: 100
        onClicked: {
            loader.sourceComponent=null;
        }
    }
}

 怎么获取component

loader的id加上item---loaderId.item返回组件根元素

Loader的异步--asynchronous

此属性保存组件是否将异步实例化。默认情况下,该属性为false。
当与源属性一起使用时,加载和编译也将在后台线程中执行。异步加载将创建组件跨多个框架声明的对象,并降低动画中的故障。当异步加载时,状态将更改为Loader.Load。一旦创建了整个组件,项目将可用,状态将更改为Loader.Ready。在进行异步加载时,将此属性的值更改为false将强制立即同步完成。如果必须在异步加载完成之前访问Loader内容,这允许开始异步加载,然后强制完成。
 

anchors怎么设置组件中根元素的位置

Text

Text组件中设置文字相关信息

Image元素

Image元素属性

source加载图片

AnimatedImage加载动态图

image只能加载静态图片

属性

暂停,是否播放等

MouseArea

鼠标区域元素

这个元素需要配合rectangle元素一起使用,需要使用rectangle包含或者填充。

因为MouseArea没有自己的边界控制范围,需要矩形框控制。

设置鼠标可控范围:

anchors.fill

 mouseArea的属性

clicked=pressed+released

mouseArea的acceptedButton默认是左键,怎么设置右键

pressButtons属性记录鼠标键值

怎么获取鼠标的左右中键值

多条件联合判断

组件检测鼠标悬浮

containsPress属性记录鼠标是否按下

containsMouse记录鼠标是否存在MouseArea区域内

containsMouse和hoverEnble有关

按下可检测

   MouseArea{
        width: 200
        height: 200

        acceptedButtons: Qt.AllButtons
        Rectangle{
            id:mouse_rect
            anchors.fill: parent
            color: "#a4e2c6"
        }
        onContainsMouseChanged: {
            console.log("Mouse cursor status:",containsMouse);
        }
        onContainsPressChanged: {
            console.log("Press status:",containsPress);
        }
    }

 悬浮可检测

   MouseArea{
        width: 200
        height: 200

        acceptedButtons: Qt.AllButtons
        hoverEnabled: true //设置悬浮使能
        Rectangle{
            id:mouse_rect
            anchors.fill: parent
            color: "#a4e2c6"
        }
        onContainsMouseChanged: {
            console.log("Mouse cursor status:",containsMouse);
        }
        onContainsPressChanged: {
            console.log("Press status:",containsPress);
        }
    }

drag---拖动属性

要设置可拖动,至少要设置:可拖动目标

如果axis(轴)没有设置,默认可随意拖动。

minimum和maximum如果没有设置,默认可随意拖动。

Rectangle {
      id: container
      width: 600; height: 200

      Rectangle {
          id: rect
          width: 50; height: 50
          color: "red"
          opacity: (600.0 - rect.x) / 600

          MouseArea {
              anchors.fill: parent
              drag.target: rect      //1---拖动的对象
              drag.axis: Drag.XAxis  //2---拖动的方向
              drag.minimumX: 0       //3---往左托的最远距离
              drag.maximumX: container.width - rect.width  //4---往右托的最远距离
          }
      }
  }

drag.filterChildren

MouseArea的drag.filterChildren如果是false则表示让这个mouseArea中的子元素mouseArea不具有(不继承)这个MouseArea的设置的属性。

注意:是mouseArea和内部mouseArea的关系,不是mouseArea和其他元素的关系。

Rectangle {
          width: 480
          height: 320
          Rectangle {
              x: 30; y: 30
              width: 300; height: 240
              color: "lightsteelblue"

              MouseArea {
                  anchors.fill: parent
                  drag.target: parent;
                  drag.axis: "XAxis"
                  drag.minimumX: 30
                  drag.maximumX: 150
                  drag.filterChildren: false

                  Rectangle {
                      color: "yellow"
                      x: 50; y : 50
                      width: 100; height: 100
                      MouseArea {
                          anchors.fill: parent
                          onClicked: console.log("Clicked")
                      }
                  }
              }
          }
      }
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick 2.7

Window {
    id:m_window
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    x:100
    y:100

   Rectangle{
       id:root
       width:300
       height: 100
       color: "#00bc12"

       MouseArea{
           id:root_mouse
           anchors.fill: parent

           drag.target: root
           //drag.axis: Drag.XAndYAxis
           drag.minimumX: 0
           drag.maximumX: m_window.width-root.width
           drag.minimumY: 0
           drag.maximumY: m_window.height-root.height
           drag.filterChildren: false

           Rectangle{
               id:mouse_rect
               width: 100
               height: 100
               color: "#ffb61e"
               MouseArea{
                   anchors.fill: parent  
               }
           }
       }
   }
}

enable

控制MouseArea是否可用(是否使能)

mouseX,mouseY

记录鼠标的坐标

hoverEnable为false时,鼠标点击,这两个属性才有用。

          Rectangle{
               id:mouse_rect
               width: 100
               height: 100
               color: "#ffb61e"
               MouseArea{
                   anchors.fill: parent
                   hoverEnabled: false
                   onMouseXChanged: {
                       console.log("Mouse x is:",mouseX);
                   }
                   onMouseYChanged: {
                       console.log("Mouse y is:",mouseY);
                   }
               }
           }

onPressAndHold槽函数----pressAndHoldInterval 

长安才会触发这个函数

长安多少时间才会触发和pressAndHoldInterval 属性有关

propagateComposedEvent---传播合成事件属性

mouse.accepted

默认情况下,各自mouseArea的事件只会是benmouseArea可以捕获;

如果需要子类的mouseArea也可以被父类捕获可以设置子类propagateComposedEvent属性和mouse.accepted属性

propagateComposedEvent属性的值为true,mouse.accepted为false表示可以向父级mouseArea传播本mouseArea的事件;

         Rectangle {
          color: "yellow"
          width: 100; height: 100

          MouseArea {
              anchors.fill: parent
              onClicked: console.log("clicked yellow")
          }

          Rectangle {
              color: "blue"
              width: 50; height: 50

              MouseArea {
                  anchors.fill: parent
                  propagateComposedEvents: true
                  onClicked: {
                      console.log("clicked blue")
                      mouse.accepted = false
                  }
                  Rectangle{
                      id:three_rect
                      width: 20
                      height: 20
                      color: "#00e500"
                      MouseArea{
                        anchors.fill: parent
                        onClicked: {
                            console.log("clicked green");
                        }
                      }
                  }
              }
          }
      }

如何向子类传播父类的事件

onDoubleClicked()

双击触发

                Rectangle{
                      id:three_rect
                      width: 20
                      height: 20
                      color: "#00e500"
                      MouseArea{
                        anchors.fill: parent
                        onClicked: {
                            console.log("clicked green");
                        }
                        onDoubleClicked: {
                            console.log("Green was double clicked");
                        }
                      }
                  }

BUTTON

button默认是有背景色的;

属性

flat

flat为truebutton没有操作时没有默认背景色 

checkable

需求:标志鼠标是否可以被选中

默认情况下button是不能被选中的,checkable为false,平淡色,如果checkable变为true,表示button可以被选中,色调加深。

注意:checkable属性并不是可选中和不可选中中的一个,而是表示button是否可以被选中。

    Button{
        id:root_button
        width: 50
        height: 50
        checkable: true
    }

atuoExclusive----自动独占属性

需求:让位于同一个元素中的所有button,任意时刻都只有一个可以被checked(选中),选中一个,其他的就自动变为未选中状态。

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick 2.7
import QtQuick.Controls 2.15

Window {
    id:m_window
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    x:100
    y:100

    Button{
        id:root_button1
        width: 50
        height: 50

        checkable: true
        autoExclusive: true
    }
    Button{
        id:root_button2
        width: 50
        height: 50
        x:60

        checkable: true
        autoExclusive: true
    }
    Button{
        id:root_button3
        width: 50
        height: 50
        x:120

        checkable: true
        autoExclusive: true
    }
}

autoRepeat

autoRepeat默认未false,如果为true,则表示如果一直按住button,就会一直触发pressed,realesed和clickedi信号。

autoRepeatDelay------按下Button之后多久触发p,r,c信号。

autoRepeatInterval---多久触发一次p,r,c信号。

text

给,button加上文字说明。

background

因为Button不是继承item,所以没有item的基础属性,比如颜色,透明度等;而如果需要设置itemd的属性,就需要background属性,background属性的值为item,可以在background的item中设置button的其他属性。

Button {
     id: control
     text: qsTr("Button")
     background: Rectangle {
         implicitWidth: 100
         implicitHeight: 40
         opacity: enabled ? 1 : 0.3
         color: control.down ? "#d0d0d0" : "#e0e0e0"
     }
 }

down

Button是否被按下

CheckBox

可选框

ChekcBox的属性

text

设置可选框的修饰文字 

tristate

控制checkbox是否具有checkstate的三种状态:

checkstate

可选框的三种状态

checkBox独占可选属性

checkBox本身并不具备像button那样的autoExclusive独占属性。

怎么办:

两种方法:

1,把checkBox组件放入buttonGroup容器种,结组button属性事项独占。

   Column{
        id:col
         CheckBox {
             checked: true
             text: qsTr("First")
         }
         CheckBox {
             text: qsTr("Second")
         }
         CheckBox {
             checked: true
             text: qsTr("Third")
         }
     }

    ButtonGroup{
        id: btng
        buttons: col.children
    }

2,在CheckBox中设置ButtonGroup.group属性的值为一个ButtonGroup组件。

    Column{
        id:col
         CheckBox {
             checked: true
             text: qsTr("First")
             ButtonGroup.group: btng
         }
         CheckBox {
             checked: true
             text: qsTr("Second")
             ButtonGroup.group: btng
         }
         CheckBox {
             checked: true
             text: qsTr("Third")
             ButtonGroup.group: btng
         }
     }

    ButtonGroup{
        id: btng
        buttons: col.children
    }

怎么设置自己想要的checkstate的三种状态的切换关系

nextCheckState

注意:这个属性后面的值是一个(回调)函数,以函数返回值作为属性的值。

    CheckBox {
        id:root_checkBox
        text:"here"
        tristate: true
        checkState: "Unchecked"
        nextCheckState: function(){
            if (checkState === Qt.Checked){
                return Qt.Unchecked;
            }
            else if (checkState === Qt.Unchecked){
                return Qt.PartiallyChecked;
            }
            else{
                return Qt.Checked;
            }
        }
    }

ButtonGroup

buttons

存放ButtonGroup需要记录的所有组件

exclusive

获取组件种的所有组件

组件.children

   Column{
        id:col
         CheckBox {
             checked: true
             text: qsTr("First")
         }
         CheckBox {
             text: qsTr("Second")
         }
         CheckBox {
             checked: true
             text: qsTr("Third")
         }
     }

    ButtonGroup{
        id: btng
        buttons: col.children
    }

RadioButton

属性

独占性

RadioButton会自动实现独占性

DelayButton

属性

Switch

条形按钮

属性

独占性

不会自动独占

需要借助ButtonGroup,像CheckBox一样使用。

TabButton

属性

独占性

自动独占

信号和槽函数

信号的定义:

signal 信号函数名()

信号触发(槽函数):

on+信号函数名:{}

信号函数名首字母大写

键盘触发的槽函数

Keys.槽函数

函数

qstr()

qsTr()函数就是 QObject::tr()函数的 QML 版本,用于返回可翻译的字符串。

real

real在qml中代表小数

怎么添加qml文件

qml文件的调用原理

项目入口是main.qml文件,文件中使用window组件实现基础的窗口。

其他自定义的文件就相当于自己定义的一个组件,可以在自定义文件中设置这个自定义组件的属性,然后在main.qml文件中通过调用自定义文件名调用自定义组件,在调用中设置自定义文件中设置的属性。

main.qml中调用的自定义组件不要再加id属性,因为main中就是使用,而不是定义了。

 main.qml调用其他文件元素和组件

qml项目运行的是main.qml文件,其他文件元素和组件要运行需要在main.qml中调用

在main.qml中直接调用其他qml文件的文件名,就会运行被调用文件中的设置。

为什么自定义文件中定义的属性不显示出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值