qml基础入门_qt qml入门-程序员宅基地

技术标签: qml  Qt/MFC  

qml是什么

概念

Qt的前端语言,可以专注于UI实现,C++实现程序逻辑,实现解耦,便于代码维护。

qml编码规范

id
属性声明
信号声明
JavaScript函数
对象属性
子对象

布局管理

事件管理

MouseArea组件

MouseArea继承自Item

  • acceptedButtons属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    MouseArea {
    
        id: mouseArea
        width: 100
        height: 100
        acceptedButtons: Qt.LeftButton | Qt.RightButton //支持左键和右键
        Rectangle {
    
            anchors.fill: parent
            color: "green"
        }
        onClicked: {
    
            console.log("onClicked")
        }
        onReleased: {
    
            console.log("onReleased")
        }
        onPressed: {
    
            var ret = pressedButtons & Qt.LeftButton
            var ret2 = pressedButtons & Qt.RightButton
            console.log(ret ? "left" : ret2 ? "right" : "other")
            console.log("onPressed")
        }
    }
}
  • containsMouse属性、ContainsPress属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    MouseArea {
    
        id: mouseArea
        width: 100
        height: 100
        acceptedButtons: Qt.LeftButton | Qt.RightButton //支持左键和右键
        hoverEnabled: true    
        cursorShape: Qt.CrossCursor   //十字光标
        Rectangle {
    
            anchors.fill: parent
            color: "green"
        }
        onClicked: {
    
            console.log("onClicked")
        }

        onHoveredChanged: {
    
            console.log("onHoveredChanged")
        }

        onContainsMouseChanged: {
    
            console.log("onContainsMouseChanged", containsMouse)
        }

        onContainsPressChanged: {
    
            console.log("onContainsPressed", containsPress)
        }
    }
}
  • drag属性

拖动控件移动

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    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
                drag.axis: Drag.XAxis
                drag.minimumX: 0
                drag.maximumX: container.width - rect.width
            }
        }
    }
}

连同子控件一起移动,由drag.filterChildren所控制

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    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: true

                Rectangle {
    
                    color: "yellow"
                    x: 50; y : 50
                    width: 100; height: 100
                    MouseArea {
    
                        anchors.fill: parent
                        onClicked: console.log("Clicked")
                    }
                }
            }
        }
    }
}

键盘事件和焦点作用域

定时器

import QtQuick 2.15
import QtQuick.Window 2.15

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

    Item {
    
        Timer {
    
            interval: 1000
            running: true
            repeat: true
            onTriggered: time.text = Date().toString()
        }

        Text {
    
            id: time
        }
    }
}

Qt Quick控件

window

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
     //root控件,父窗口是主界面
    width: 640
    height: 480
    visible: true

    //相对于父控件的偏移量
    x: 100
    y:100


    minimumWidth: 400   //最小宽度
    minimumHeight: 300  //最小高度
    maximumWidth: 600   //最大宽度
    maximumHeight: 450  //最大高度

    opacity: 0.9 //0-1,窗口透明度

    onWidthChanged: {
    
        console.log("width: ", width)
    }

    Button {
    
        id: btn1
        width: 80
        height: 80
        focus: true
        objectName: "btn1"
        background: Rectangle {
    
            border.color: btn1.focus ? "blue" : "red"
        }
        onClicked: {
    
            console.log("btn1 clicked")
        }
        Keys.onRightPressed: {
    
            btn2.focus = true
        }
    }

    Button {
    
        id: btn2
        x: 120
        width: 80
        height: 80
        objectName: "btn2"
        background: Rectangle {
    
            border.color: btn2.focus ? "blue" : "red"
        }
        onClicked: {
    
            console.log("btn2 clicked")
        }
        Keys.onLeftPressed: {
    
            btn1.focus = true
        }
    }

    //保存了整个窗口中当前获取焦点的控件
    onActiveFocusItemChanged: {
    
        console.log("active focus item changed", activeFocusItem, activeFocusItem.objectName)
    }

    title: qsTr("my qml")
}

在这里插入图片描述

Item与Rectangle

Rectangle控件:自身属性不多,但它继承自Item,因此Item的诸多属性可以使用

  • focus属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Rectangle {
    
        x: 100
        y: 100
        z: 1
        width : 100
        height: 50
        color: "red"
        focus: false  //当前控件可获取焦点

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

        Keys.onReturnPressed: {
    
            console.log("on return pressed")
        }

    }

    Rectangle {
    
        x: 120
        y: 120
        width : 100
        height: 50
        color: "green"
    }
}
  • anchor属性
  1. anchors.fill → \to 填充父控件
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Rectangle {
    
        id: rect1
        anchors.fill: parent
        color: "red"
    }

    Rectangle {
    
        id: rect2
        width : 100
        height: 50
        color: "green"
    }
}

在这里插入图片描述

  1. anchors.leftanchors.leftMarginanchors.topanchors.topMargin
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

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

    Rectangle {
    
        id: rect2
        width : 100
        height: 50
        anchors.left: rect1.right
        anchors.leftMargin: 20
        color: "green"
    }

    Rectangle {
    
        id: rect3
        width : 100
        height: 50
        anchors.top: rect1.bottom
        anchors.topMargin: 20
        color: "blue"
    }
}

在这里插入图片描述
3. anchors.centerInanchors.horizontalCenteranchors.verticalCenter

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Rectangle {
    
        id: rect1
        width : 100
        height: 50
        color: "red"
        //anchors.centerIn: parent
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
    }
}

在这里插入图片描述
4. border

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Rectangle {
    
        id: rect1
        x: 320
        y: 240
        width : 100
        height: 100
        color: "red"

        border.color: "blue"
        border.width: 3

		radius: 5
    }
}

在这里插入图片描述
5. gradient

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Rectangle {
    
        id: rect1
        x: 320
        y: 240
        width : 100
        height: 100
        color: "red"

        gradient: Gradient {
    
                 GradientStop {
     position: 0.0; color: "lightsteelblue" }
                 GradientStop {
     position: 1.0; color: "blue" }
             }
    }
}

在这里插入图片描述

Rectangle自定义边框

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    MyRectangle {
    
        x: 200
        y: 200

        myTop: 10
        myBottom: 10
    }
}

MyRectangle.qml

import QtQuick 2.15

Rectangle {
    
    id: borderRect
    property int myTop: 0
    property int myBottom: 0
    width: 200
    height: 100
    color: "red"
    Rectangle {
    
        id: innerRect
        color: "blue"
        anchors.fill: parent
        anchors.topMargin: myTop
        anchors.bottomMargin: myBottom
        anchors.leftMargin: 5
        anchors.rightMargin: 5
    }
}

在这里插入图片描述

states与transitions

Item的两个重要属性:statestransitions

状态机states

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Rectangle {
    
         id: root
         width: 100; height: 100
         color: "blue"

         state: "normal"

         states: [
             State {
    
                 name: "red_color"
                 PropertyChanges {
     target: root; color: "red"; width: 200 }
             },
             State {
    
                 name: "blue_color"
                 PropertyChanges {
     target: root; color: "blue"; height: 200 }
             },
             State {
    
                 name: "normal"
                 PropertyChanges {
     target: root; color: "black"; height: 200; width: 200 }
             }
         ]

         MouseArea {
    
             anchors.fill: parent
             onPressed: {
    
                 root.state = "red_color"
             }
             onReleased: {
    
                 root.state = "blue_color"
             }
         }
     }
}

transitions

  1. 第一种方法:直接属性动画

点击控件产生渐变效果

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    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   //持续时间(ms)
         }

         NumberAnimation {
    
             id: animateOpacity
             target: flashingblob
             properties: "opacity"
             from: 0.5
             to: 1.0
             duration: 1000   //持续时间(ms)
        }
     }
}

点击控件产生伸长效果

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

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

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

         NumberAnimation {
    
             id: animateOpacity
             target: flashingblob
             properties: "width"
             from: 75
             to: 150
             duration: 3000   //持续时间(ms)
        }
     }
}
  1. 第二种方法:使用预定义的目标与属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

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

        PropertyAnimation on x {
     //修改当前控件的位置
            to: 100
            duration: 1000
        }

        PropertyAnimation on y {
    
            to: 100
            duration: 1000
        }
    }
}

还可以定义动画的执行顺序

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

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

        SequentialAnimation on color {
    
            ColorAnimation {
     to: "yellow"; duration: 1000 }
            ColorAnimation {
     to: "blue"; duration: 1000 }
        }
    }
}
  1. 第三种:在状态改变的时候做动画
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    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: [
             Transition {
    
                 from: "PRESSED"
                 to: "RELEASED"
                 ColorAnimation {
     target: button; duration: 1000 }
             },
             Transition {
    
                 from: "RELEASED"
                 to: "PRESSED"
                 ColorAnimation {
     target: button; duration: 1000 }
             }
         ]
     }
}
  1. 第四种:预定好行为
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

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

        MouseArea {
    
            anchors.fill: parent
            onClicked: {
    
                ball.x += 50
                ball.y += 50
            }
        }

        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 }
        }
    }
}

Component和Loader

qmlwindow组件也是一个Component

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Component.onCompleted: {
    
        console.log("onCompleted", width, height, color)
    }

    Component.onDestruction: {
    
        console.log("onDestruction")
    }
}

ComponentLoader配合使用加载控件,在加载控件完成后想对控件进行修改,可使用loader.item属性对控件进行修改

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Button {
    
        id: btn
        x: 200; y:0
        width: 50; height: 50
        onClicked: {
    
            //loader.sourceComponent = null
            loader.item.width = 50
            loader.item.height = 50
            loader.item.color = "blue"
            console.log("onClicked")
        }
    }

    Component {
    
        id: com
        Rectangle {
    
            width: 100; height: 100
            color: "red"
        }
    }

    Loader {
    
        id: loader
        asynchronous: true     //异步加载
        sourceComponent: com
        source: "./MyRectangle.qml"
        onStatusChanged: {
    
            console.log("status: ", loader.status)
        }
    }
}

加载图片

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Component {
    
        id: com
        Image {
    
            id: img
            source: "./asset/image.png"
        }
    }

    Loader {
    
        id: loader
        asynchronous: true
        sourceComponent: com
        source: "./MyRectangle.qml"
        onStatusChanged: {
    
            console.log("status: ", loader.status)
        }
    }
}

在这里插入图片描述
加载动图

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Component {
    
        id: com
        AnimatedImage {
    
            id: img
            source: "/asset/test.gif"
            width: 100
            height: 100
        }
    }

    Loader {
    
        id: loader
        asynchronous: true
        sourceComponent: com
        source: "./MyRectangle.qml"
        onStatusChanged: {
    
            console.log("status: ", loader.status)
        }
    }
}

Button组件

Button控件继承自AbstractButtonAbstractButton继承自ControlControl继承自Item

  • autoExclusive属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Button {
    
        id: btn1
        width: 50
        height: 50
        checkable: true
        autoExclusive: true
    }

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

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

同一时间只有一个按钮处于checked状态

在这里插入图片描述

  • autoRepeatautoRepeatDelayautoRepeatInterval
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Button {
    
        id: btn1
        width: 50
        height: 50

        autoRepeat: true
        autoRepeatDelay: 3000 //控制第一次重复触发的时间
        autoRepeatInterval: 1000 //重复触发的时间间隔

        onClicked: {
    
            console.log("onClicked")
        }
        onReleased: {
    
            console.log("onReleased")
        }
        onPressed: {
    
            console.log("onPressed")
        }
    }
}
  • icon属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Button {
    
        id: btn1
        width: 50
        height: 50

        icon.source: "/asset/8666542_save_icon.png"
        icon.color: "black"
    }
}

在这里插入图片描述

  • text属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Button {
    
        id: btn1
        width: 50
        height: 20

        text: "btn"
    }
}

在这里插入图片描述

  • background属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Button {
    
        id: btn1
        width: 50
        height: 20

        background: Rectangle {
    
            anchors.fill: btn
            color: "blue"
        }
    }
}

在这里插入图片描述

Property的使用

MyRectangle.qml

import QtQuick 2.15

Rectangle {
    
    id: borderRect
    width: 200
    height: 200
    color: "red"

    property int myTop: 0
    property int myBottom: 0
    property real myReal: 0.0
    property string myString: "black"
    property color myColor: "red"
    property url myUrl: "/asset/test.jpg"

    required property Component myCom    //外界一定设置才行
    property Rectangle myRect

    property var myVar: "0.0"
    property list<Rectangle> myList

    readonly property int rectWidth: width //外界不可修改
    property alias newInnerRect: innerRect //给子控件取别名

    Rectangle {
    
        id: innerRect
        Loader {
    
            id: loader
            sourceComponent: myCom
        }
        color: "blue"
        anchors.fill: parent
        anchors.topMargin: myTop
        anchors.bottomMargin: myBottom
        anchors.leftMargin: 5
        anchors.rightMargin: 5
    }
}

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Component {
    
        id: com
        Button {
    
            width: 50
            height: 50
        }
    }

    MyRectangle {
    
        id: rect
        myCom: com
        Component.onCompleted: {
    
            newInnerRect.color = "green"
            console.log(rectWidth)
        }
    }
}

在这里插入图片描述

CheckBox控件

CheckBox继承自AbstractButton

  • tristate 属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Column {
    
        CheckBox {
    
            checked: true
            tristate: true
            text: qsTr("First")
            onCheckStateChanged: {
    
                console.log("checkState: ", checkState)
            }
        }
        CheckBox {
    
            text: qsTr("Second")
        }
        CheckBox {
    
            checked: true
            text: qsTr("Third")
        }
    }
}


checkBox控件无法用autoExclusive属性实现单选框,但可用ButtonGroup来实现

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    ButtonGroup {
    
        id: childGroup
        exclusive: true
        buttons: column.children
    }

    Column {
    
        id: column
        CheckBox {
    
            checked: true
            text: qsTr("First")

        }
        CheckBox {
    
            text: qsTr("Second")
        }
        CheckBox {
    
            checked: true
            text: qsTr("Third")
        }
    }
}

在这里插入图片描述

以下示例说明了如何将子项的组合检查状态绑定到父复选框的检查状态

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    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
        }
    }
}

在这里插入图片描述

  • nextCheckState
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    CheckBox {
    
        tristate: true

        nextCheckState: function() {
    
            if (checkState === Qt.Checked)
                return Qt.Unchecked
            else
                return Qt.Checked

        }
    }
}

DelayButton控件

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    DelayButton {
    
        width: 150
        height: 50
        delay: 3000
        onPressedChanged: {
    
            console.log(progress)
        }
    }
}

在这里插入图片描述

RadioButton控件

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Column {
    
        RadioButton {
    
            checked: true
            text: qsTr("First")
        }
        RadioButton {
    
            text: qsTr("Second")
        }
        RadioButton {
    
            text: qsTr("Third")
        }
    }
}

RadioButton控件具有自动排他性

在这里插入图片描述

Switch控件

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    ButtonGroup {
    
        id: btngrp
        exclusive: true
        buttons: column.children
    }

    Column {
    
         id: column
         Switch {
    
             text: qsTr("Wi-Fi")
             onPositionChanged: {
    
                 console.log("pos: ",position)
             }
             onVisualPositionChanged: {
    
                 console.log("vis pos: ", visualPosition)
             }
         }
         Switch {
    
             text: qsTr("Bluetooth")
         }
     }
}

在这里插入图片描述

TabButton控件

一般用作切换界面的按钮

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    TabBar {
    
         TabButton {
    
             text: qsTr("Home")
         }
         TabButton {
    
             text: qsTr("Discover")
             //width: 80
         }
         TabButton {
    
             text: qsTr("Activity")
         }
     }
}

在这里插入图片描述

Button扩展

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Button {
    
        id: control
        text: qsTr("Button")
        contentItem: Rectangle {
    
            color: "transparent" //默认颜色是白色
            Text {
    
                text: control.text
                font.pixelSize: 18
                font.bold: true
                font.italic: true
                x: 28; y: 5
            }
            Image {
    
                id: img
                source: "/asset/rocket.png"
                width: 25
                height: 25
            }
        }
    }
}

在这里插入图片描述

Text控件

  • elide属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Rectangle {
    
        width: 80
        height: 30
        anchors.centerIn: parent
        border.color: "red"
        Text {
    
            id: txt
            elide: Text.ElideMiddle
            anchors.fill: parent
            text: qsTr("https://example.com/sjdflk/shdlsj/sdflksjf")
        }
    }
}

在这里插入图片描述

  • font属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")


    Text {
    
        id: txt
        text: qsTr("https://example.com\nhttps://\nsss.com")
        font.bold: true //粗体
        font.family: "Courier New"  //字体
        font.italic: true  //斜体
        font.letterSpacing: 3 //字体间距离
        //font.pixelSize: 36  //字体 像素为单位
        font.pointSize: 20  //字体 磅
        font.underline: true
        lineHeight: 2 //行间距

        Component.onCompleted: {
    
            console.log("lineCount: ", lineCount)
        }
    }
}

在这里插入图片描述

  • textFormat属性
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")


    Column {
    
        Text {
    
            font.pointSize: 24
            text: "<b>Hello</b> <i>World!</i>"
        }
        Text {
    
            font.pointSize: 24
            textFormat: Text.RichText
            text: "<b>Hello</b> <i>World!</i>"
        }
        Text {
    
            font.pointSize: 24
            textFormat: Text.PlainText
            text: "<b>Hello</b> <i>World!</i>"
        }
        Text {
    
            font.pointSize: 24
            textFormat: Text.MarkdownText
            text: "**Hello** *World!*"
        }
    }
}

在这里插入图片描述

  • linkActivated信号
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")


    Text {
    
            textFormat: Text.RichText
            text: "See the <a href=\"http://qt-project.org\">Qt Project website</a>."

            MouseArea {
    
                anchors.fill:  parent
                cursorShape: Qt.PointingHandCursor
                hoverEnabled: true
                
                onClicked: {
    
                    
                }
            }
 
            //将被MouseArea拦截失效
            onLinkActivated: {
    
                console.log(link + " link activated")
            }

            onLinkHovered: {
    
                console.log("hover", link)
            }

            onHoveredLinkChanged: {
    
                console.log("hover link changed: ", hoveredLink)
            }
    }
}

在这里插入图片描述

Label控件

Label继承自Text,专门用于单行展示文字。

Popup和Overlay

在这里插入图片描述

当Popup为子控件时,且设置visible为true时,仍然可以显示

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Rectangle {
    
        width: 100; height: 100
        color: "red"
        visible: false

        Popup {
    
            width: 50; height: 50
            visible: true
        }
    }
}

在这里插入图片描述

Popup的z顺序是个例外

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Rectangle {
    
        width: 100; height: 100
        color: "red"
        visible: true
    }

    //Popup的z顺序为例外
    Popup {
    
        width: 50; height: 50
        x: 20; y: 20
        //color: "blue"
        visible: true
        z: -1
    }
}

在这里插入图片描述

  • closePolicy属性:窗口关闭逻辑

MyPopup.qml

import QtQuick 2.15
import QtQuick.Controls 2.5

Popup {
    
    id: popup
    x: 100
    y: 100
    width: 200
    height: 300
    visible: true
    modal: true
    closePolicy: Popup.NoAutoClose
}

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Popup {
    
        width: 50; height: 50
        x: 20; y: 20
        //color: "blue"
        visible: true
        z: -1
    }

    MyPopup {
    

    }
}

如此,按下Esc或者在Popup控件周围按下不会让控件消失

在这里插入图片描述

  • modal模态对话框属性
  • dim:配合modal使用
  • enterexit属性
import QtQuick 2.15
import QtQuick.Controls 2.5

Popup {
    
    id: popup
    x: 100
    y: 100
    width: 200
    height: 300
    visible: true
    modal: true
    dim: true
    //closePolicy: Popup.NoAutoClose

    enter: Transition {
     //打开的时候
             NumberAnimation {
     property: "opacity"; from: 0.0; to: 1.0 }
    }

    exit: Transition {
     //推出的时候
             NumberAnimation {
     property: "opacity"; from: 1.0; to: 0.0 }
    }
}
  • contentItem属性
import QtQuick 2.15
import QtQuick.Controls 2.5

Popup {
    
    id: popup
    x: 100; y: 100
    width: 400; height: 300
    visible: true
    modal: true
    dim: true
    //closePolicy: Popup.NoAutoClose

    enter: Transition {
     //打开的时候
             NumberAnimation {
     property: "opacity"; from: 0.0; to: 1.0 }
    }

    exit: Transition {
     //推出的时候
             NumberAnimation {
     property: "opacity"; from: 1.0; to: 0.0 }
    }

    contentItem: Rectangle {
    
        anchors.fill: parent
        Text {
    
            id: txt
            text: qsTr("Message Box popup")
        }
    }

    Button {
    
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 30
        anchors.right: parent.right
        anchors.rightMargin: 30
        text: "cancel"
    }

    Button {
    
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 30
        anchors.right: parent.right
        anchors.rightMargin: 150
        text: "ok"
    }
}

在这里插入图片描述

  • overlay属性
import QtQuick 2.15
import QtQuick.Controls 2.5

Popup {
    
    id: popup
    x: 100; y: 100
    width: 400; height: 300
    visible: true
    modal: true
    dim: true
    //closePolicy: Popup.NoAutoClose

    enter: Transition {
     //打开的时候
             NumberAnimation {
     property: "opacity"; from: 0.0; to: 1.0 }
    }

    exit: Transition {
     //推出的时候
             NumberAnimation {
     property: "opacity"; from: 1.0; to: 0.0 }
    }

    contentItem: Rectangle {
    
        anchors.fill: parent
        Text {
    
            id: txt
            text: qsTr("Message Box popup")
        }
    }

    Button {
    
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 30
        anchors.right: parent.right
        anchors.rightMargin: 30
        text: "cancel"
    }

    Button {
    
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 30
        anchors.right: parent.right
        anchors.rightMargin: 150
        text: "ok"
    }

    Overlay.modal: Rectangle {
    
        color: "#33000000"
    }

    Overlay.modeless: Rectangle {
    
        color: "blue"
    }
}

Reapter

model属性

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Row {
    
        Repeater {
    
            model: 3 //模型, 数字表示有几个控件
            Rectangle {
    
                width: 100; height: 40
                border.width: 1
                color: "yellow"
            }
        }
    }
}

在这里插入图片描述

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.5

Window {
    
    width: 640
    height: 480
    visible: true
    title: qsTr("my qml")

    Repeater {
    
        model: ["Button", "Rectangle", "MouseArea"]

        Button {
    
            y: index * 50
            width: 100; height: 40
            text: modelData
        }
    }
}

在这里插入图片描述

Combox控件

Combox控件继承自ControlControl继承自Item

MyComboBox.qml

import QtQuick 2.5
import QtQuick.Controls 2.5

ComboBox {
    
    editable: true
    model: ListModel {
    
        id: model
        ListElement {
     text: "Banana" }
        ListElement {
     text: "Apple" }
        ListElement {
     text: "Coconut" }
    }
    onAccepted: {
    
        if (find(editText) === -1)
            model.append({
    text: editText})
    }
}

在这里插入图片描述

  • currentTextcurrentValue
import QtQuick 2.5
import QtQuick.Controls 2.15

ComboBox {
    
    textRole: "text"
    valueRole: "name"
    displayText: currentText + " " + currentValue

    model: [
        {
     value: 100, text: qsTr("No modifier"), name: "lindong" },
        {
     value: 200, text: qsTr("Shift") , name: "xiaoyan" },
        {
     value: 300, text: qsTr("Control"), name: "muchen" }
    ]

    onCurrentTextChanged: {
    
        console.log("text: ", currentText)
    }

    onCurrentValueChanged: {
    
        console.log("value: ", currentValue)
    }
}

在这里插入图片描述

  • validator

此属性保存可编辑组合框的输入文本验证器。设置验证器后,文本字段将仅接受使文本属性处于中间状态的输入。仅当按下 Return 或 Enter 键时文本处于可接受状态时,才会发出接受的信号。

import QtQuick 2.5
import QtQuick.Controls 2.15

ComboBox {
    
    model: 10
    editable: true
//    validator: IntValidator {
    
//        top: 9
//        bottom: 0
//    }

    validator: RegExpValidator {
    
        regExp: /[0-9A-F]+/
    }

    onAcceptableInputChanged: {
      //当前有没有匹配validator验证器
        console.log(acceptableInput)
    }
}

自定义ComboBox

  • indicator

此属性保存放置指示器项。

import QtQuick 2.12
import QtQuick.Controls 2.12

ComboBox {
    
    id: control
    model: ["First", "Second", "Third"]

    delegate: ItemDelegate {
     //针对model中 每一项的具体绘制
        width: control.width
        contentItem: Text {
    
            text: modelData
            color: "red"
            font: control.font
            elide: Text.ElideRight
            verticalAlignment: Text.AlignVCenter
        }
        highlighted: control.highlightedIndex === index
    }

    indicator: Canvas {
    
        id: canvas
        x: control.width - width - control.rightPadding
        y: control.topPadding + (control.availableHeight - height) / 2
        width: 12
        height: 8
        contextType: "2d"

        Connections {
    
            target: control
            function onPressedChanged() {
     canvas.requestPaint(); }
        }

        onPaint: {
    
            context.reset();
            context.moveTo(0, 0);
            context.lineTo(width, 0);
            context.lineTo(width / 2, height);
            context.closePath();
            context.fillStyle = control.pressed ? "#17a81a" : "#21be2b";
            context.fill();
        }
    }

    contentItem: Text {
     //控件显示内容
        leftPadding: 0
        rightPadding: control.indicator.width + control.spacing

        text: control.displayText
        font: control.font
        color: control.pressed ? "red" : "blue"
        verticalAlignment: Text.AlignVCenter
        elide: Text.ElideRight
    }

    background: Rectangle {
      //控件背景
        implicitWidth: 120
        implicitHeight: 40
        border.color: control.pressed ? "#17a81a" : "#21be2b"
        border.width: control.visualFocus ? 2 : 1
        radius: 3
    }

    popup: Popup {
      //绘制整个下拉控件
        y: control.height - 1
        width: control.width
        implicitHeight: contentItem.implicitHeight
        padding: 1

        contentItem: ListView {
    
            clip: true
            implicitHeight: contentHeight
            model: control.popup.visible ? control.delegateModel : null
            currentIndex: control.highlightedIndex

            ScrollIndicator.vertical: ScrollIndicator {
     }
        }

        background: Rectangle {
    
            border.color: "gray"
            radius: 2
        }
    }
}

Shape控件

与ShapePath结合使用可以绘制曲线

模型和视图

ListView

MyListView.qml

import QtQuick 2.15
import QtQuick.Controls 2.5

ListView {
    
    width: 180; height: 200

    model: ['Button', 'Rectangle', "List", "CheckBox"]        //数字, 控制所有数据
    spacing: 10

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

在这里插入图片描述
还可以用ListModel这么搞

import QtQuick 2.15
import QtQuick.Controls 2.5

ListView {
    
    width: 180; height: 200

    model:  ListModel {
    
        ListElement {
    
            name: "Bill Smith"
            number: "555 3264"
        }
        ListElement {
    
            name: "John Brown"
            number: "555 8426"
        }
        ListElement {
    
            name: "Sam Wise"
            number: "555 0473"
        }
    }//控制所有数据
    spacing: 10

    delegate: Button {
     //控制每一项数据如何绘制
        text: name + ": " + number
    }
}

在这里插入图片描述

  • highlight属性
import QtQuick 2.5
import QtQuick.Controls 2.5

ListView {
    
    id: list
    width: 180; height: 200

    model:  ListModel {
    
        ListElement {
    
            name: "Bill Smith"
            number: "555 3264"
        }
        ListElement {
    
            name: "John Brown"
            number: "555 8426"
        }
        ListElement {
    
            name: "Sam Wise"
            number: "555 0473"
        }
    }//控制所有数据
    spacing: 15

    highlight: Rectangle {
    
        color: "lightsteelblue"
        //radius: 5
    }

    delegate: Rectangle {
     //控制每一项数据如何绘制
        width: 80
        height: 15
        color: "transparent"

        Text {
    
            id: txt
            text: name
        }

        MouseArea {
    
            anchors.fill: parent
            onClicked: {
    
                currentIndex = index
                console.log(index)
            }
        }
    }
}

在这里插入图片描述

  • headfoot
import QtQuick 2.5
import QtQuick.Controls 2.5

Rectangle {
    
    width: 400
    height: 200

    border.color: "black"
    anchors.centerIn: parent

    ListView {
    
        id: list
        width: 180; height: 200

        model:  ListModel {
    
            ListElement {
    
                name: "Bill Smith"
                number: "555 3264"
            }
            ListElement {
    
                name: "John Brown"
                number: "555 8426"
            }
            ListElement {
    
                name: "Sam Wise"
                number: "555 0473"
            }
        }//控制所有数据

        header: Rectangle {
    
            width: 180
            height: 20

            color: "red"
        }

        footer: Rectangle {
    
            width: 180
            height: 20

            color: "blue"
        }

        spacing: 15

        highlight: Rectangle {
    
            color: "lightsteelblue"
            //radius: 5
        }

        delegate: Rectangle {
     //控制每一项数据如何绘制
            width: 80
            height: 15
            color: "transparent"

            Text {
    
                id: txt
                text: name
            }

            MouseArea {
    
                anchors.fill: parent
                onClicked: {
    
                    list.currentIndex = index
                    console.log(index)
                }
            }
        }
    }
}

在这里插入图片描述

  • section
import QtQuick 2.5
import QtQuick.Controls 2.5

Rectangle {
    
    width: 400
    height: 200

    border.color: "black"
    anchors.centerIn: parent

    ListView {
    
        id: list
        width: 180; height: 200

        Component {
    
            id: sectionHeading
            Rectangle {
    
                width: 400
                height: childrenRect.height
                color: "blue"

                required property string section

                Text {
    
                    text: parent.section
                    font.bold: true
                    font.pixelSize: 20
                }
            }
        }

        model:  ListModel {
    
            ListElement {
    
                name: "Bill Smith"
                number: "555 3264"
                size: "s"
            }
            ListElement {
    
                name: "John Brown"
                number: "555 8426"
                size: "l"
            }
            ListElement {
    
                name: "Sam Wise"
                number: "555 0473"
                size: "xl"
            }
        }//控制所有数据

//        header: Rectangle {
    
//            width: 180
//            height: 20

//            color: "red"
//        }

//        footer: Rectangle {
    
//            width: 180
//            height: 20

//            color: "blue"
//        }

        spacing: 15

        highlight: Rectangle {
    
            color: "lightsteelblue"
            //radius: 5
        }

        delegate: Rectangle {
     //控制每一项数据如何绘制
            width: 80
            height: 15
            color: "transparent"

            Text {
    
                id: txt
                text: name
            }

            MouseArea {
    
                anchors.fill: parent
                onClicked: {
    
                    list.currentIndex = index
                    console.log(index)
                }
            }
        }

        section.property: "size"
        section.criteria: ViewSection.FullString
        section.delegate: sectionHeading  //每一个property如何绘制
    }
}

在这里插入图片描述

StackView

可用于管理具有多个页面的应用程序

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    
     title: qsTr("Hello World")
     width: 640
     height: 480
     visible: true

     StackView {
    
         id: stack
         initialItem: mainView
         anchors.fill: parent
     }

     Component {
    
         id: mainView

         Row {
    
             spacing: 10

             Button {
    
                 text: "Push"
                 onClicked: stack.push(mainView)
             }
             Button {
    
                 text: "Pop"
                 enabled: stack.depth > 1
                 onClicked: stack.pop()

             }
             Text {
    
                 text: stack.depth
             }
         }
     }
 }

在这里插入图片描述

自定义Model

ListView显示数据必须构造相应的模型类,继承自QAbstractListModel

mylistmodel.h

#ifndef MYLISTMODEL_H
#define MYLISTMODEL_H

#include <QAbstractListModel>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonValue>

class MyListModel : public QAbstractListModel
{
    
    Q_OBJECT

public:
    enum MyRoleName {
    
        Name = Qt::DisplayRole + 1,
    };

    explicit MyListModel(QObject *parent = nullptr);
    static MyListModel* instance();

    // Basic functionality:
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    QHash<int, QByteArray> roleNames() const override;

private:

    QList<QString> m_data;
};

#endif // MYLISTMODEL_H

mylistmodel.cpp

#include "mylistmodel.h"

MyListModel::MyListModel(QObject *parent)
    : QAbstractListModel(parent)
{
    
    m_data.append("韩立 200");
    m_data.append("银月 666");
    m_data.append("紫灵 111");
}

MyListModel *MyListModel::instance()
{
    
    static MyListModel* obj = new MyListModel;
    return obj;
}

int MyListModel::rowCount(const QModelIndex &parent) const
{
    
    // For list models only the root node (an invalid parent) should return the list's size. For all
    // other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
    if (parent.isValid())
        return 0;

    return m_data.count();
    // FIXME: Implement me!
}

QVariant MyListModel::data(const QModelIndex &index, int role) const
{
    
    if (!index.isValid())
        return QVariant();

    if (role == MyRoleName::Name) {
    
        return m_data[index.row()];
    }

    // FIXME: Implement me!
    return QVariant();
}

QHash<int, QByteArray> MyListModel::roleNames() const
{
    
    QHash<int, QByteArray> roles;
    roles.insert(MyRoleName::Name, "name");
    return roles;
}

main.cpp中注册模型类

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "mylistmodel.h"

int main(int argc, char *argv[])
{
    
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("MyListModel", MyListModel::instance());
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
        &app, [url](QObject *obj, const QUrl &objUrl) {
    
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

qml当中用ListView显示

import QtQuick 2.15
import QtQuick.Window 2.15

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

    ListView {
    
        width: 200
        height: 300

        model: MyListModel

        delegate: Text {
    
            id: txt;
            text: name
        }
    }
}

在这里插入图片描述

布局

锚点布局

定位器

Row

Column

布局管理器

RowLayout

ColumnLayout

C++类的自定义属性使用

非单例类

在C++类中利用Q_PROPERTY关键字自定义属性,并绑定到qml端的通用流程:

  1. 在继承自QObject类的MyObject类中声明:
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)

因为只有继承自QObject才能使用属性系统

  1. 对于非单例类,将其注册到元对象系统中
qmlRegisterType<MyObject>("sy", 1, 0, "MyObject");
  1. 对于非单例类,在qml端的调用C++属性方法,需要实例化
// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import sy 1.0

ApplicationWindow {
    
    visible: true
    width: 400
    height: 200
    title: "Using C++ Property in QML"

    MyObject {
    
        id: myCppObject
    }

    Column {
    
        anchors.centerIn: parent
        spacing: 10

        Text {
    
            text: "Name from C++: " + myObject.path
        }

        TextField {
    
            placeholderText: "Enter new name"
            onTextChanged: myObject.path = text
        }
    }
}

在这里插入图片描述

单例类

  1. 单例类注册到元对象系统的方式为
qmlRegisterSingletonInstance("sy", 1, 0, "MyObject", MyObject::instance());
  1. 对于单例类,在qml端的调用C++属性方法,不需要实例化
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import sy 1.0

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

    Column {
    
        anchors.centerIn: parent
        spacing: 10

        Text {
    
            text: "Name from C++: " + MyObject.path
        }

        TextField {
    
            placeholderText: "Enter new name"
            onTextChanged: MyObject.path = text
        }
    }
}

在qml侧调用C++的函数

无论是C++中的属性还是方法,都需要将C++的类注册到元对象系统中,主要是三种方法。

C++类实例作为上下文对象嵌入到qml代码中

  1. Q_INVOKABLE宏将C++函数申明为元对象系统可调用的函数
Q_INVOKABLE int getValue();
  1. 注册对象至元对象系统中
MyObject obj;
engine.rootContext()->setContextProperty("myQml", &obj);
  1. qml调用:无需实例化,也无需import
import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    
    visible: true
    width: 400
    height: 200
    title: "Using C++ function in QML"

    Button{
    
        id:btn
        height: 48
        width: 120
        text: "1"
        anchors.centerIn: parent

        Component.onCompleted: {
    
            text = myQml.getValue()
            console.log(text)
        }
    }
}

在这里插入图片描述

非单例类使用qmlRegisterType注册为一个可实例化的qml类型

  1. 注册
qmlRegisterType<MyObject>("sy", 1, 0, "myQml");
  1. 在qml侧:需要import并且实例化对象后调用
// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import sy 1.0

ApplicationWindow {
    
    visible: true
    width: 400
    height: 200
    title: "Using C++ function in QML"

    MyObject {
    
        id: myQml
    }

    Button{
    
        id:btn
        height: 48
        width: 120
        text: "1"
        anchors.centerIn: parent

        Component.onCompleted: {
    
            text = myQml.getValue()
            console.log(text)
        }
    }
}

单例类使用qmlRegisterSingletonInstance注册为单例类型

  1. 注册
qmlRegisterSingletonInstance("sy", 1, 0, "myQml", MyObject::instance());
  1. 需要import,但不需要实例化
// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import sy 1.0

ApplicationWindow {
    
    visible: true
    width: 400
    height: 200
    title: "Using C++ function in QML"

    MyObject {
    
        id: myQml
    }

    Button{
    
        id:btn
        height: 48
        width: 120
        text: "1"
        anchors.centerIn: parent

        Component.onCompleted: {
    
            text = myQml.getValue()
            console.log(text)
        }
    }
}

信号与槽

C++声明信号与槽

  1. 信号声明
写在signals下
返回值是void,只需声明,无需实现
可以有参数
可以重载(一般不用重载)
  1. 槽函数声明
写在public slots下
返回值是void,需声明,需实现
可以有参数
可以重载(一般不用重载)
  1. C++对象的信号槽绑定
connect(信号的发送者,发送的信号(函数地址),信号的接受者,处理的槽函数(函数地址));

qml的信号与信号处理器

  1. 信号声明
siganl mouseReleased()
signal actionCanceled(string action)

手动发射信号:

对象id.mouseReleased()

除了可以自己定义信号,QML类型提供了一种内建的属性值改变信号。当属性值改变时,QML会自动发出该信号。

  1. 信号处理器
当在QML对象中添加一个信号时,会自动添加一个对应的信号处理器

范例:

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import sy 1.0

Window {
    
    id: root
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    signal modify()

    Column {
    
        anchors.centerIn: parent
        spacing: 10

        Text {
    
            text: "Name from C++: " + MyObject.path
        }

        TextField {
    
            placeholderText: "Enter new name"
            onTextChanged: {
    
                MyObject.path = text
                root.modify()
            }
        }
    }

    onModify: {
    
        console.log("text is modified.")
    }
}
  1. 使用connect将信号连接到一个方法或另一个信号
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import sy 1.0

Window {
    
    id: root
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    signal sigModify()

    function onModify()
    {
    
        console.log("modify")
    }

    Column {
    
        anchors.centerIn: parent
        spacing: 10

        Text {
    
            text: "Name from C++: " + MyObject.path
        }

        TextField {
    
            id: textField
            placeholderText: "Enter new name"
            onTextChanged: {
    
                MyObject.path = text
                root.sigModify()
            }
        }
    }

    Component.onCompleted: {
    
        root.sigModify.connect(onModify)
    }
}

  1. Connections在发射信号的对象外部进行信号处理

范例

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import sy 1.0

Window {
    
    id: root
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    Column {
    
        anchors.centerIn: parent
        spacing: 10

        Text {
    
            text: "Name from C++: " + MyObject.path
        }

        TextField {
    
            id: textField
            placeholderText: "Enter new name"
        }
    }

    Connections {
    
        target: textField
        function onTextChanged() {
    
            console.log("modify")
            MyObject.path = text
        }
    }
}

C++信号绑定到qml

一般来讲,C++中自定义的属性会绑定到qml侧,当属性改变信号发出时,C++和qml端都能响应。

其次,C++自定义的信号可以通过connect绑定到qml端的JavaScript函数进行处理。

qml信号绑定到C++

一般点击qml控件上发出的信号,在qml侧使用信号处理器处理,然后在信号处理器中调用C++函数就可以了。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Star_ID/article/details/132169011

智能推荐

fopen,fopen_s,_wfopen_s与_fsopen, _wfsopen的区分_fopen_s和fopen的区别-程序员宅基地

文章浏览阅读1.5w次,点赞2次,收藏13次。C++做项目的过程中,需要实现文件打开保存的一个功能,当我对文件tmp.dat进行写操作以后,想要第二次对此文件进行写操作,此时用fopen_s,_wfopen_s均出现返回int error = 13也就是EACCES (Permission denied)的错误。而由于项目是Unicode编码,没办法用fopen进行文件操作(其实只要在预编译中加入_CRT_SECURE_NO_WARN_fopen_s和fopen的区别

合工大计算机组成原理ppt,合工大 计算机组成原理 计算机组成原理提纲.pdf-程序员宅基地

文章浏览阅读251次。合工大 计算机组成原理 计算机组成原理提纲计算机组成原理计算机组成原理合肥工业大学计算机与信息学院陈陈 田田2013.12.12提 纲11 考试形式和试卷结构考试形式和试卷结构2 考查目标3 参考书目44 考点及重点难点分析考点及重点难点分析计算机与信息学院 ..._计算机组成原理合工大

PostgreSQL--读懂执行计划(一)_postgresql 执行计划-程序员宅基地

文章浏览阅读7.9k次,点赞5次,收藏42次。这里写自定义目录标题前言执行计划常用命令参数解读常用组合执行计划解读关键字常见扫描方式Seq ScanIndex Only ScanIndex ScanBitmap Index Scan+Bitmap Heap ScanHash JoinNested LoopMerge Join小结前言PostgreSQL为每个收到查询产生一个查询计划。 选择正确的计划来匹配查询结构和数据的属性对于好的性能来说绝对是最关键的,因此系统包含了一个复杂的规划器来尝试选择好的计划。 你可以使用EXPLAIN命令察看规划器为任_postgresql 执行计划

释放AI创作潜能:从大模型训练到高产力应用-程序员宅基地

文章浏览阅读1.4w次,点赞83次,收藏82次。随着科技的不断进步,人工智能已经成为了各行各业的必备技能。特别是在内容创作领域,人工智能生成内容(AIGC)正逐渐成为趋势。AI可以创造出优秀的、原创的文章和故事,这为创作者们提供了一种新的创作方式。同时,AIGC技术也可以节省人力成本,提高内容生产效率。但是,如何在使用技术的前提下保持内容的原创性和质量,这是我们需要思考的问题。

mysql root 访问被拒绝_mysql-“连接失败:用户'root'@'localhost'(使用密码:是)的访问被拒绝”...-程序员宅基地

文章浏览阅读3.7k次。mysql-“连接失败:用户'root'@'localhost'(使用密码:是)的访问被拒绝”这个问题在这里已有答案:MySQL错误1045(28000):用户'bill'@'localhost'的访问被拒绝(使用密码:是) 35个答案我写了一些PHP网页使用的函数,以便与mysql数据库进行交互。 当我在服务器上测试它们时,..._mysql -uroot -p 数据库访问拒绝oot @localhost

【分布式缓存】springboot整合jetcache使用详解_springboot集成jetcache如何操作jetcache-程序员宅基地

文章浏览阅读5k次,点赞103次,收藏105次。springboot整合jetcache使用详解_springboot集成jetcache如何操作jetcache

随便推点

Tensorflow-gpu 1.13.1+Python 3.7.2+CUDA 10.0 +cuDNN7.5_tensorflow-gpu==1.13.1需要那个版本的python-程序员宅基地

文章浏览阅读8.3k次,点赞3次,收藏20次。最近在工作站上安装Tensorflow-gpu失败了很多次,由于坚信Tensorflow 1.13.1对Python3.7和新的CUDA的支持,一直没有放弃,现在终于配置成功了,把过程简单记录下来,希望能对大家有帮助。【电脑基础环境】硬件:工作站,显卡Nvidia quadro M5000软件:windows 7【软件安装过程】Anaconda3下载地址:https://www.a..._tensorflow-gpu==1.13.1需要那个版本的python

静态编译的方式合并第三方dll,并生成自己的dll,以及出现‘__acrt_first_block == header’异常解决方式_vs 将opencv的dll打包到自己的dll-程序员宅基地

文章浏览阅读4.7k次,点赞2次,收藏8次。有时候调用了第三方的dll,但是由于种种原因不能显示出来,需要将第三方dll封装到自己的dll里,在使用时,让别人只你的dll,而不用调用你使用的第三方dll。怎么实现?用静态编译的方式!最近由于项目需要,用VS2015+opencv2.4.13编程实现了静态编译生成自己的dll,这个dll相当于将opencv的部分功能封装到自己的dll中了(不要跟我说opencv开源,不需要封装到自己的d..._vs 将opencv的dll打包到自己的dll

unity Android安卓平台读取Application.persistentDataPath路径_unity怎么 读取 application.persistentdatapath 下的文件-程序员宅基地

文章浏览阅读3.1k次。这次这么测试是对的,下次再有问题再看看写入的时候这样写的: fileLocal = Application.persistentDataPath + "/" + path; finalPath =#if UNITY_ANDROID && !UNITY_EDITOR fileLocal;#else "file://" + fileLocal;#endif读取的时候这样写的: path =#._unity怎么 读取 application.persistentdatapath 下的文件

C语言 数据结构 栈的顺序表示和实现-程序员宅基地

文章浏览阅读2.8k次,点赞7次,收藏47次。栈的顺序表示和实现文章目录1 顺序栈结构2 基本操作函数3 整体代码test3.cStack.h4 运行结果5 附加题栈的存储结构可以是顺序表或链表,该篇为顺序表存储栈是后进先出的数据结构1 顺序栈结构栈结构体top永远指向下一个typedef struct Stack{ DataType data[maxn]; // 作为栈元素的存储方式,数据类型为DataType int top; // top即栈顶指_栈的顺序表示和实现

总结Vue中index.html、main.js、App.vue、index.js之间关系以及Vue项目加载流程_index.html 是vue 项目的-程序员宅基地

文章浏览阅读7.9k次,点赞15次,收藏105次。总结Vue中index.html、main.js、App.vue、index.js之间关系以及Vue项目加载流程文章目录总结Vue中index.html、main.js、App.vue、index.js之间关系以及Vue项目加载流程1 vue中index.html、main.js、App.vue、index.js关系简介1.1 项目的运行入口index.html1.2 入口文件main.js1.3 根组件App.vue1.4 控制路由index.js2 Vue项目加载流程1 vue中index.html_index.html 是vue 项目的

lammps数据后处理:python绘制应力应变曲线 附程序代码_混凝土应力应变曲线图绘制代码-程序员宅基地

文章浏览阅读1.7k次。绘制应力应变的方法有很多,常规的做法是把数据文件拖入到origin绘图,还有一个简单的方法是使用python脚本,在模拟完成后,直接运行一下脚本就能得到应力应变曲线,可以快速的观察运行结果。_混凝土应力应变曲线图绘制代码