QML知识学习(持续更新)

QML重点知识学习

看了以下qgc的源代码,发现里面用到的了很多qml的知识,这是为之前没有接触过的,学习一下。

创建Qt Quick Application —> Qt quick

1. QML之Window

这一部分使用时候一定要注意在文档中(Qt助手)查看属性value的类型

//main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15

Window {
    width: 640
    height: 300
    color: "pink"
    visible: true
    //其他的窗口可以设置为false
    title: qsTr("chuanjiujiu")
    x:100
    y:200
    //相对于父控件的位置,window是root控件,其父控件是主界面
    maximumHeight: 400
    //最大最小窗口
    opacity: 0.5
    //窗口透明度

    //在qml中信号与槽简单化了
    signal mySig()//自定义一个信号
    onMySig: {
        //on+信号名称 触发信号
    }

    //Window里自带的一些属性也可以被触发
    onWidthChanged: {
        console.log("width:", width)
    }

    //可以创建自定义属性
    property int myValue: 0
    onMyValueChanged: {
    }//会自动生成可触发属性

    Button{
        id: btn1//此时id是为了在qml里可以通过id来访问其他控件
        width: 50
        height: 50
        focus: true
        objectName: "btn1"
        //string类型
        //这里是为了在控制台容易辨别这个按钮 起一个名字 否则在控制台是编号
        background: Rectangle{
            border.color: btn1.focus ? "blue" : "black"
        }
        Keys.onRightPressed: {
            btn2.focus = true
        }
    }

    Button{
        id: btn2//此时id是为了在qml里可以通过id来访问其他控件
        x:100
        width: 50
        height: 50
        objectName: "btn2"
        background: Rectangle{
            border.color: btn2.focus ? "blue" : "black"
        }
        Keys.onLeftPressed: {
            btn1.focus = true
        }
    }

    onActiveFocusItemChanged: {
        console.log("active focus item changed", activeFocusItem)
    }
    //这个是找到丢失的focus 在控制台打印
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cJLJxSAp-1691552214499)(/home/cjj/.config/Typora/typora-user-images/image-20230801150941383.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FheDQjlE-1691552214500)(/home/cjj/.config/Typora/typora-user-images/image-20230801152948154.png)]

2. QML之Rectangle

Rectangle自己的属性不多,不过它继承自Item,可以看Item的属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6pt0WInS-1691552214501)(/home/cjj/.config/Typora/typora-user-images/image-20230801160014849.png)]

Focus的使用

Rectangle {
        x:50
        y:50
        width: 100
        height: 100
        color: "blue"
        focus: true
        //activeFocus

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

        Keys.onReturnPressed: {
            console.log("on return pressed")
        }//这个地方要配合focus为true使用 此时控件获取焦点可以检测到回车
    }

锚点anchors

控件填充整个父控件fill

Rectangle {
        id:rect1
        anchors.fill: parent//此时parent是Window
        width: 100
        height: 50
        color: "black"
    }

控件布局leftMargin

Rectangle {
        id:rect1
        width: 100
        height: 50
        color: "black"
    }

    Rectangle {
        id:rect2
        width: 100
        height: 50
        anchors.left: rect1.right//此时两个矩形在同一行
        anchors.leftMargin: 20//两个矩形之间的空隙
        anchors.top: rect1.bottom//一列
        anchors.centerIn: parent//居中于父控件
        anchors.horizontalCenter: parent.horizontalCenter//横向居中
        anchors.verticalCenter: parent.verticalCenter//垂直居中
        color: "black"
    }

让控件旋转rotation

Rectangle {
        id:rect1
        width: 100
        height: 50
        color: "black"
        
        rotation: 30//让元素旋转 30度
    }

放缩控件scale

Rectangle {
        id:rect1
        width: 100
        height: 50
        color: "black"

        scale: 2//放大原来的两倍
    }

Rectangle自己的属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-21imA0Bi-1691552214501)(/home/cjj/.config/Typora/typora-user-images/image-20230802100504142.png)]

//渐变
Rectangle {
         y: 100
         width: 80
         height: 80
         gradient: Gradient {
             GradientStop { position: 0.0; color: "lightsteelblue" }
             GradientStop { position: 1.0; color: "blue" }
        }
    }
    
    Rectangle {
         y: 200; width: 80; height: 80
         rotation: 90
         gradient: Gradient {
             GradientStop { position: 0.0; color: "lightsteelblue" }
             GradientStop { position: 1.0; color: "blue" }
        }
    }     
Rectangle实现自定义边框

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kTnjCNzz-1691552214502)(/home/cjj/.config/Typora/typora-user-images/image-20230802103111006.png)]

//自定义边框
//MyRectangle.qml
Rectangle{
    id: borderRect
    property int myTopMargin: 0//把属性暴露出去可以外部修改
    color: "black"
    Rectangle{
        id:innerRect
        color: "blue"
        anchors.fill: parent
        anchors.topMargin: 0
        anchors.bottomMargin: myTopMargin
        anchors.rightMargin: 0
        anchors.leftMargin: 0
    }
}
    
//main.qml
//调用MyRectangle
Window {
    width: 640
    height: 300
    color: "pink"
    visible: true
    //其他的窗口可以设置为false
    title: qsTr("chuanjiujiu")

    //可以直接调用Rectangle 并修改自定义属性
    MyRectangle{
        x:100
        y:50
        width: 200
        height: 100
        myTopMargin: 10
    }

}

3. QML之动画-Item的states/transition

states

Rectangle {
        id: root
        width: 100; height: 100

        state: "red_color"
        //此时是通过state而非color修改颜色
        //目的是可以比较方便的修改控件当前的状态,比如颜色宽度等
        //我自己认为是封装起来可以方便修改属性

        states: [
            State {
                name: "red_color"
                PropertyChanges { target: root; color: "red" }
            },
            State {
                name: "blue_color"
                PropertyChanges { target: root; color: "blue" }
            }
        ]
    }

    MouseArea{
        anchors.fill: parent
        onPressed: {
            root.state = 'blue_color'
        }//按下鼠标变成蓝色

        onReleased: {
            root.state = 'red_color'
        }//松开鼠标变成红色
    }

transitions直接修改使用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: 1000//持续时间
         }

         NumberAnimation {
             id: animateOpacity
             target: flashingblob
             properties: "opacity"
             from: 0.1
             to: 1.0
             duration: 2000//持续时间
         }
     }

**transitions的ProperyAnimation on 属性值 { to: }**使用on开启动画

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

         PropertyAnimation on x { to: 100 }
         PropertyAnimation on y { to: 100 }
         //修改当前控件位置
         
         //ProperyAnimation on 属性值 { to: }
         //修改属性值
}

还会有其他ColorAnimation on color、SequentialAnimation on color等动画效果

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: "lightblue"}
             },
             State {
                 name: "RELEASED"
                 PropertyChanges { target: button; color: "lightsteelblue"}
             }
         ]
    
         transitions: [//使用transitions从一个状态切换到另一个状态
             Transition {
                 from: "PRESSED"
                 to: "RELEASED"
                 ColorAnimation { target: button; duration: 100}
             },
             Transition {
                 from: "RELEASED"
                 to: "PRESSED"
                 ColorAnimation { target: button; duration: 100}
             }
         ]
     }

Behavior

Rectangle {
         width: 75; height: 75; radius: width
         id: ball
         color: "salmon"

         MouseArea{
             anchors.fill: parent
             onClicked: {
                 ball.x +=50
                 ball.y +=40
             }
         }
        //点击之后Behavior才会被触发 本例子是bounce弹跳
         Behavior on x {
             NumberAnimation {
                 id: bouncebehavior
                 easing {
                     type: Easing.OutElastic
                     amplitude: 1.0
                     period: 0.5
                 }
             }
         }
         Behavior on y {
             animation: bouncebehavior
         }
         Behavior {
             ColorAnimation { target: ball; duration: 100 }
         }
     }

4. QML之Component/Loader

Window {
    //root控件 父窗口是主界面
    width: 640
    height: 300
    color: "pink"
    visible: true
    //其他的窗口可以设置为false
    title: qsTr("chuanjiujiu")

    //此时的Componet是包含root控件的组件
    Component.onCompleted: {
        console.log('oncom')//界面创建的时候就触发了onCompleted打印了oncom
    }
    
    Component.onDestruction: {
        //在窗口销毁时调用
    }
}

Componet可以理解为root组件,onCompleted会在root控件生成的时候被触发,也就是窗口生成的时候,此时可以打印一些有用的信息。

同时我们也可以自己创建Componet组件,组件内部是我们需要封装的Rectangle控件,和普通控件不同的是,Component需要我们手动加载,也就是用Loader加载。(这里是异步加载的概念)

已经加载的组件修改item

此时可以使用Loader的item属性修改

Component{
        id: com
        Rectangle{
            width: 200
            height: 100
            color: 'black'
        }
    }

    //使用Loader加载上面的Componet
    Loader{
        id: loader
        sourceComponent: com
        onStateChanged: {

        }
    }

    Button{
        width: 50
        height: 50
        x:250
        onClicked: {
            //此时loader.item就是上面的Componet(com)里的Rectangle
            //loader加载的最top-level的控件
            loader.item.width=50
            loader.item.height=50
            loader.item.color='blue'
        }
    }

Loader的不同状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EzXR48Q2-1691552214503)(/home/cjj/.config/Typora/typora-user-images/image-20230803102752139.png)]

asynchronous 异步加载此时Loader状态为Loading

Image加载在Component里使用image{}加载静态图片

5. QML之MouseArea

MouseArea默认颜色和背景色一样,所以可以在里面套一个Rectangle

MouseArea{
        id:mouseArea
        width: 200
        height: 200
        Rectangle{
            anchors.fill: parent
            color: 'red'
        }
    	onclicked{
            //触发点击后执行
        }
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lKadYfjl-1691552214503)(/home/cjj/.config/Typora/typora-user-images/image-20230803104704898.png)]

acceptedButtons: Qt::MouseButtons支持左键或者右键或者其他

MouseArea{
        id:mouseArea
        width: 200
        height: 200
		//左右建都可以触发事件
        acceptedButtons: Qt.LeftButton | Qt.RightButton

        Rectangle{
            anchors.fill: parent
            color: 'red'
        }

        onClicked: {
            console.log('click')
        }

        //pressedButtons这个属性只能在onPressed里用
    	//Click不可以用因为此时已经释放release
        onPressed: {
            var ret = pressedButtons & Qt.LeftButton
            console.log(ret ? 'left' : 'right')
        }
    }

drag可以拖动组件详见Qt助手手册

6. QML之Button

Button

Button如果想设置样式要在Button里放上Rectangle来设置。

Button{
        id:btn
        width: 150
        height: 100
        Rectangle{
            anchors.fill: parent
            color: btn.checked | btn.down ? 'blue' : 'black'
            //在内部控件中要通过id来调用属性
            //btn.checked
        }
    }
Button扩展
DelayButton

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YrfMIZDx-1691552214503)(/home/cjj/.config/Typora/typora-user-images/image-20230803155048203.png)]

RedioButton

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TSAwPs9B-1691552214504)(/home/cjj/.config/Typora/typora-user-images/image-20230803155140353.png)]

Switch

实现单选都要用ButtonGround

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BPzOUt1d-1691552214504)(/home/cjj/.config/Typora/typora-user-images/image-20230803155248879.png)]

TabBar默认单选
contentItem实现按钮的重绘
 Button {
     id: control
     text: qsTr("Button")
     contentItem: Label {
         text: control.text
         font: control.font//可以调整字体大小
         verticalAlignment: Text.AlignVCenter
     }
     //还可以使用Image放按钮图片
 }

7. QML之Property

Property的基本用法是Property int Myid = 3,基本的变量类型都可使用,包括color、url等。

动态加载组件

//MyRectangle.qml
Rectangle{
    id: myrec
    width: 200
    height: 200
    color: "black"
    property Component myCom //把属性暴露出去可以外部修改
    Rectangle{
        id:innerRect
        color: "blue"

        //加载外面传进来的Component
        //这里传入button
        Loader{
            id:loader
            sourceComponent: myCom
        }

        anchors.fill: parent
        anchors.topMargin: 0
        anchors.bottomMargin: 10
        anchors.rightMargin: 0
        anchors.leftMargin: 0
    }
}

//main.qml
//外部定义Componet
Component{
        id:com
        Button{
            width: 50
            height: 50
        }
    }
//在MyRectangle里调用
MyRectangle{
        myCom: com
    }   

还有通用类型var类型,可以传入任何类型,list类型,动态创建数组。

希望外部访问不希望被修改(类似getter)

在属性前加上readonly,readonly Property int Myid = 3

必须赋值才能继续的情况(必须setter)

在属性前加上required,required Property int Myid = 3

外部访问子控件

使用property alias newName: oldName在控件外面写一个别名,这样外部就可以访问到控件里的属性/控件

8. QML之CheckBox

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s1LDJ7Sh-1691552214505)(/home/cjj/.config/Typora/typora-user-images/image-20230803153425267.png)]

包括CheckBox在内的很多控件都继承在AbstractButton

CheckBox效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RkY7AOjw-1691552214506)(/home/cjj/.config/Typora/typora-user-images/image-20230803153605171.png)]

tristate实现三态
单选框实现
//使用ButtonGroup实现
ButtonGroup{
        id: childGroup
        exclusive: true//排他
        buttons: col.children
    }

Column {
        id: col
        CheckBox {
            checked: true
            text: qsTr("First")
            //ButtonGroup.group: childGroup
            //第二种方法
        }
        CheckBox {
            text: qsTr("Second")
        }
        CheckBox {
            checked: true
            text: qsTr("Third")
        }
    }
全选功能
Column {
     ButtonGroup {
         id: childGroup
         exclusive: false
         checkState: parentBox.checkState
     }

     CheckBox {
         id: parentBox
         text: qsTr("Parent")
         checkState: childGroup.checkState
     }

     CheckBox {
         checked: true
         text: qsTr("Child 1")
         leftPadding: indicator.width
         ButtonGroup.group: childGroup
     }

     CheckBox {
         text: qsTr("Child 2")
         leftPadding: indicator.width
         ButtonGroup.group: childGroup
     }
 }

9. QML之Text

可以设置字体之类的

10. QML之Popup与Oerlay

也就是弹窗

11. QML之Repeater

重复器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Po1YpApj-1691552214506)(/home/cjj/.config/Typora/typora-user-images/image-20230804122845850.png)]

Repeater{
        model: 3 //模型 如果是数字的话 表示有几个模型/控件

        Rectangle{
            y: index*50
            width:100
            height: 40
            border.width: 1
            color: 'yellow'
        }
    }

重复器不仅可以是数字,还可以是数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RISZc11c-1691552214506)(/home/cjj/.config/Typora/typora-user-images/image-20230804123310146.png)]

Repeater{
        model: ['no.1','no.2','no.3']

        Button{
            y: index*50
            width:100
            height: 40
            text: modelData//modelData可以获取model数组的值
        }
    }

12. QML之ListView

ListView {
         width: 180; height: 200

         model: 3//控制所有数据

         spacing: 10//控制控件之间距离

         delegate: Button {//控制每一项数据是如何绘制的
             text: index
         }
     }

13. QML之ComboBox

就是下拉菜单控件,可以参考文档

14. QML之focus-FocusScope

15. QML之信号与槽

自己定义qml端的交互

connect连接

//自己写一个信号
signal testSig(string s, int val)

//处理信号的函数
function func(ss, ii){
        console.log(ss, ii)
    }

//触发信号
Button{
        id:btn
        width: 50
        height: 50
        onClicked: {
            testSig('cjj', 22)
        }
    }

//接收信号并处理
Component.onCompleted: {
        testSig.connect(func)
    }  

使用connection连接更简单

Window {
    //root控件 父窗口是主界面
    id: window
    width: 640
    height: 300
    color: "pink"
    visible: true
    //其他的窗口可以设置为false
    title: qsTr("chuanjiujiu")

    //自己写一个信号
    signal testSig(string s, int val)


    //触发信号
    Button{
        id:btn
        width: 50
        height: 50
        onClicked: {
            testSig('cjj', 22)
        }
    }

    //接收信号
    Connections{
        target: window//谁发出信号
        onTestSig:{
            console.log(s, val)
        }
    }

    //接收信号方法2
//    Connections{
//        target: window//谁发出信号
//        function onTestSig(str, iValue){
//            console.log(str, iValue)//此时可以自己指定参数名
//        }
//    }
}
自定义组件的信号与槽

16. QML之C++交互

创建自定义对象
QML端发送信号
C++端信号绑定
C++端直接调用QML端函数

17. QML之各类布局

18. QML之自定义Grid控件与OpacityMargin

19. QML之访问复杂组件的子组件

20. QML之Timer

21. QML之Model

22. QML之ChartView

23. QML之ListView

24. QML之动画效果Glow和发射器Emittert

25. QML之FolderListModel

26. QML之Settings

27. QML之打包成dll

28. QML之提示信息

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值