《Qt Quick核心编程 》 学习

知识点:

自定义按钮:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Button {
        id:btn
        x: 0
        y: 62
        text: "Quit2"
        style:ButtonStyle {
            background: Rectangle {
                implicitWidth: 100
                implicitHeight: 25
                border. btn.pressed ? 2 : 1
            }
        }
    }

}
main.qml

多个窗口:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 1.4

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600


    Button {  // 会默认放到   data 列表中
        id:btn
        text: "Quit"
    }
    Window {
        id: root2
        visible: true
        title: qsTr("Hello World")
         300
        height: 100
        flags: Qt.Popup

        Text{
            text: "Hello Qt Quick"
        }

    }


}
main.qml

颜色 LinearGradient :

import QtQuick 2.12
import QtQuick.Window 2.12
import QtGraphicalEffects 1.12

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
         500
        height: 500
        border.color: Qt.lighter("purple")
        border. 2
        radius: 15
        LinearGradient {
            anchors.fill: parent
            start: Qt.point(0, 0)
            end: Qt.point(500, 500)
            gradient: Gradient {
                GradientStop {
                    position: 0.000
                    color: Qt.rgba(1, 0, 0, 1)
                }
                GradientStop {
                    position: 0.167
                    color: Qt.rgba(1, 1, 0, 1)
                }
                GradientStop {
                    position: 0.333
                    color: Qt.rgba(0, 1, 0, 1)
                }
                GradientStop {
                    position: 0.500
                    color: Qt.rgba(0, 1, 1, 1)
                }
                GradientStop {
                    position: 0.667
                    color: Qt.rgba(0, 0, 1, 1)
                }
                GradientStop {
                    position: 0.833
                    color: Qt.rgba(1, 0, 1, 1)
                }
                GradientStop {
                    position: 1.000
                    color: Qt.rgba(1, 0, 0, 1)
                }
            }
            source:  Image { source:"images/ufo.png" }
        }

        Component.onCompleted: {
            console.log(color.r,color.g,color.b,color.a);
        }
    }



}
main.qml

Text 控件 多余文字显示 三个点:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtGraphicalEffects 1.12

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600
    color: "cyan"

    Rectangle{
        id:rect1
        color: "purple"
         150
        height: 100

        Text {
            id: txt1
            anchors.fill:parent
            text: qsTr("<h1>Hello Red Text,Hello Red Text,Hello Red Text,Hello Red Tex</h1>")
            color:"red"


            clip: true
            wrapMode: Text.WrapAnywhere
            elide: Text.ElideRight
        }

    }
}
View Code

Image 相关:

显示GIF 图片:

Image不能显示GIF,因为Image只能显示静态图片,可以使用 AnimatedImage 显示动态图片
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600
    color: "cyan"

    Image {
        id: img1
         100
        height: 100
        source: "images/1.gif" // 不能显示GIF,因为Image只能显示静态图片
    }
    // 可以使用 AnimatedImage 显示动态图片
    AnimatedImage {
        id:aniImg1
        x:100
        y:100
         100
        height: 100
        source: "images/1.gif"
    }


}
View Code

异步加载网络图片:

使用了 BusyIndicator 组件

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600
    color: "cyan"

    Rectangle{
         500
        height: 500
        border.color: "red"
        border. 2
        BusyIndicator{
            id:loading
            running: true
            anchors.centerIn: parent
            z:2 // z-index
        }
        Text {
            id: desc
            visible: false
            anchors.centerIn: parent
            z:3 // z-index
        }


        Image {
            id: img1
            cache: false //  在加载大型图片一般不要进行缓存
            anchors.fill: parent
            source: "http://pic1.juimg.com/161122/330846-16112222051832-lp.jpg"
            fillMode: Image.PreserveAspectFit
            asynchronous: true // 开启异步加载 图片  网络资源自动就是异步,本地资源默认都是同步
            onStatusChanged: {
                if(img1.status === Image.Loading){
                    loading.running = true;
                    desc.visible = false;
//                    console.log("loading");
                }else if(img1.status === Image.Ready){
                    loading.running = false;
//                    console.log("ready");

                }else if(img1.status === Image.Error){
                    loading.running = true;
                    desc.visible = true;
                    desc.text = "load img error";
//                    console.log("error");
                }
            }



//           focus: true
//           Keys.onPressed: {
//               if(event.key === Qt.Key_A){
//                   console.log(img1.status,"||||   ",Image.Error);

//               }
//           }




        }
    }


}
View Code

效果:

图片查看器(一次打开单张图片):

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.10
import QtQuick.Dialogs 1.3

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600
    minimumWidth: 480
    minimumHeight: 360
    BusyIndicator{
        id:loading
        running: false
        anchors.centerIn: parent
        z:2
    }

    Text {
        id: stateTxt
        visible: false
        anchors.centerIn: parent
        z:3
    }
    Image {
        id: imageViewer
        asynchronous: true // 异步加载
        cache: false // 关闭缓存
        anchors.fill: parent
        fillMode: Image.PreserveAspectFit
        onStatusChanged: {
            if(imageViewer.status === Image.Loading){
                loading.running = true;
                stateTxt.visible = false;
            }else if(imageViewer.status === Image.Ready){
                loading.running = false;
            }else if(imageViewer.status === Image.Error){
                loading.running = true;
                stateTxt.visible = true;
                stateTxt.text = "load image error";
            }
        }
    }

    Button{
        id:openFile
        text: "Open"
        anchors.left: parent.left
        anchors.leftMargin: 8
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 8
        onClicked:fileDialog.open()
    }
    FileDialog{
        id:fileDialog
        title: "Please choose a file"
        nameFilters: ["Image Files (*.jpg *.png *.gif)"]
        onAccepted: {
            imageViewer.source = fileDialog.fileUrl;
            var imageFile =new String(fileDialog.fileUrl);
            imagePath.text = imageFile.slice(8);
        }
    }
    Text {
        id: imagePath
        anchors.left: openFile.right
        anchors.leftMargin: 8
        anchors.verticalCenter: openFile.verticalCenter
        font.pixelSize: 18
    }

}
main.qml

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.10
import QtQuick.Dialogs 1.3

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600
    minimumWidth: 480
    minimumHeight: 360
    BusyIndicator{
        id:loading
        running: false
        anchors.centerIn: parent
        z:2
    }

    Text {
        id: stateTxt
        visible: false
        anchors.centerIn: parent
        z:3
    }
    Image {
        id: imageViewer
        asynchronous: true // 异步加载
        cache: false // 关闭缓存
        anchors.fill: parent
        fillMode: Image.PreserveAspectFit
        onStatusChanged: {
            if(imageViewer.status === Image.Loading){
                loading.running = true;
                stateTxt.visible = false;
            }else if(imageViewer.status === Image.Ready){
                loading.running = false;
            }else if(imageViewer.status === Image.Error){
                loading.running = true;
                stateTxt.visible = true;
                stateTxt.text = "load image error";
            }
        }
    }

    Button{
        id:openFile
        text: "Open"
        anchors.left: parent.left
        anchors.leftMargin: 8
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 8
        onClicked:fileDialog.open()
    }
    FileDialog{
        id:fileDialog
        title: "Please choose a file"
        nameFilters: ["Image Files (*.jpg *.png *.gif)","Bitmap Files (*.bmp)","* (*.*)"]
        selectedNameFilter:"Image Files (*.jpg *.png *.gif)" // 默认过滤器
        selectMultiple: true  // 选择多个文件
        onAccepted: {
            imageViewer.source = fileDialog.fileUrls[0];
            var imageFile =new String(fileDialog.fileUrl[0]);
            imagePath.text = imageFile.slice(8);
        }
    }
    Text {
        id: imagePath
        anchors.left: openFile.right
        anchors.leftMargin: 8
        anchors.verticalCenter: openFile.verticalCenter
        font.pixelSize: 18
    }

}
一次可以选择多个文件

Loader:

Loader 用来动态加载QML Component 组件,

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.10
import QtQuick.Dialogs 1.3

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Loader{
        id:redLoader
        anchors.left: parent.left
        anchors.leftMargin: 4
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 4
        sourceComponent: colorComponent
        onLoaded: {
            item.color = "red"; // 这里的item 指的是 所加载的顶层对象即 rect
        }
    }

    Component{
        id:colorComponent  // 注Component 中只能有一个id 属性 和 一个顶层对象!!!
        Rectangle{
            id:rect
             50
            height: 50
            signal zcb(color clr)
            MouseArea{
                anchors.fill: parent
                onPressed: rect.zcb(rect.color)
            }
            onZcb:{
                rect.color = "yellow";
            }
        }

    }







}
View Code

如果Loader加载的Item 想要处理按键事件,必须要把Loader 中的 focus 设置为true

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.10
import QtQuick.Dialogs 1.3

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Loader{
        id:redLoader
        anchors.left: parent.left
        anchors.leftMargin: 4
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 4
        sourceComponent: colorComponent
        onLoaded: {
            item.color = "red";
        }
        // 如果Loader加载的Item 想要处理按键事件,必须要把Loader focus 设置为true,这样它所加载的组件才可以接收到focus
        focus: true // 开启按键事件

    }

    Component{
        id:colorComponent
        Rectangle{
            id:rect
             50
            height: 50
            signal zcb(color clr)
            MouseArea{
                anchors.fill: parent
                onPressed: rect.zcb(rect.color)
            }
            onZcb:{
                rect.color = "yellow";
            }
            focus: true
            Keys.onPressed: {
                console.log(event.key);
                event.accepted = true;
            }

        }

    }







}
View Code

从文件中加载组件:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.10
import QtQuick.Dialogs 1.3

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Loader{
        id:redLoader
        anchors.left: parent.left
        anchors.leftMargin: 4
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 4
//        sourceComponent: colorComponent
        source: "MyTest.qml"
        onLoaded: {
            console.log(item); //此时 item  仍然是顶层对象
            item.color = "red";
        }
        // 如果Loader加载的Item 想要处理按键事件,必须要把Loader focus 设置为true,这样它所加载的组件才可以接收到focus
        focus: true // 开启按键事件

    }

}
main.qml
import QtQuick 2.10

Rectangle{
    id:colorComponent
     50
    height: 50
    signal zcb(color clr)
    MouseArea{
        anchors.fill: parent
        onPressed: colorComponent.zcb(colorComponent.color)
    }
    onZcb:{
        colorComponent.color = "yellow";
    }

    focus:true
    Keys.onPressed: {
        console.log(event.key);
        event.accepted = true;
    }

}
MyTest.qml

动态创建和销毁控件:

利用Loader,可以通过设置source为 空串,设置sourceComponent 为undefined 可以销毁控件 ~

在js 中动态创建组件对象:

有两种方式:

1,使用Qt.createComponent()  动态创建一个组件对象,然后使用Component 的createObject() 创建它的实例对象。 

2,使用Qt.createQmlObject()  从一个QML字符串直接创建一个实例对象

注:

如果已经有一个QML文件中定义了一个组件,你想创建它的实例对象,这时使用1较好。

如果QML对象本身是在运行时产生的,那么Qt.createQmlObject() 可能是比较好的选择。 

第一种,

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.10
import QtQuick.Dialogs 1.3

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
        anchors.fill: parent

        focus: true
        Keys.onPressed: {
            if(event.key === Qt.Key_A){
                // 创建组件对象
                var newCom = Qt.createComponent("MyTest.qml");
                newCom.createObject(rect,{"color":"cyan"});// 第一个参数为父级,后面是新创建组件的属性

            }

        }

    }




}
main.qml
import QtQuick 2.10

Rectangle{
    id:colorComponent
     50
    height: 50
    signal zcb(color clr)
    MouseArea{
        anchors.fill: parent
        onPressed: colorComponent.zcb(colorComponent.color)
    }
    onZcb:{
        colorComponent.color = "yellow";
    }

    focus:true
    Keys.onPressed: {
        console.log(event.key);
        event.accepted = true;
    }

}
MyTest.qml

第二种,

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.10
import QtQuick.Dialogs 1.3

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
        anchors.fill: parent

        focus: true
        Keys.onPressed: {
            if(event.key === Qt.Key_A){
                // 创建组件对象
                var newCom = Qt.createQmlObject('import QtQuick 2.0; Rectangle {color: "red";  20; height: 20;}',
                                                   rect,
                                                   "newCom01"); // 第三个参数 是给对象关联一个文件路径,主要用于报告错误
            }

        }

    }


}
main.qml

销毁动态创建的对象:

这里说的销毁不是仅仅把对象的visible 设为false或者是opacity 设置为0 。

需要调用 destroy() 函数,

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.10
import QtQuick.Dialogs 1.3

Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
        anchors.fill: parent

        property var mycom: null

        focus: true
        Keys.onPressed: {
            if(event.key === Qt.Key_A){
                // 创建组件对象
                rect.mycom = Qt.createQmlObject('import QtQuick 2.0; Rectangle {color: "red";  20; height: 20;}',
                                                   rect,
                                                   "newCom01"); // 第三个参数 是给对象关联一个文件路径,主要用于报告错误
            }
            if(event.key === Qt.Key_B){
                console.log(rect.mycom);
                rect.mycom.destroy(0); // 0s  后销毁

            }

        }

    }


}
main.qml

点击a 创建,点击b 销毁~

Qt Quick 元素布局:

三大类:

1,前面说过的 锚布局(Anchor),它是利用Item 的anchors 属性实现,非常方便!!!

2,定位器(Position),它包含了Row(行定位器),Column(列定位器),Grid(表格定位器),Flow(流定位器)

3,布局管理器(Layout),它包含  行布局(RowLayout),列布局(ColumnLayout),表格布局(GridLayout)

定位器Position

布局管理器Layout 

Qml 的布局管理器和 Qt widgets 相似,它与定位器的不同之处在于:布局管理器会自动调整子Item 的尺寸来适应界面大小的变化。

要使用布局管理器,需要引入Layouts 模块。

GridLayout:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rootItem
         360
        height: 240
        color:"#eee"

        GridLayout{
             200
            anchors.left: parent.left
            anchors.leftMargin: 4
            anchors.top: parent.top
            anchors.topMargin: 4
            rows:2
            columns: 2
            rowSpacing: 4
            columnSpacing: 4


            Rectangle{
                id:rect1
                100
                height: 100
                color: "purple"
                Layout.columnSpan: 2
                Layout.rowSpan: 2
                Layout.fillWidth: true

            }

            Rectangle{
                id:rect2
                100
                height: 100
                color: "cyan"
            }
            Rectangle{
                id:rect3
                100
                height: 100
                color: "yellow"
            }
        }










    }


}
main.qml

RowLayout

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rootItem
         400
        height: 240
        color:"#eee"

        RowLayout{
             400
            anchors.left: parent.left
            anchors.leftMargin: 4
            anchors.top: parent.top
            anchors.topMargin: 4

            Rectangle{
                id:rect1
                100
                height: 100
                color: "purple"

            }

            Rectangle{
                id:rect2
                100
                height: 100
                color: "cyan"
            }
            Rectangle{
                id:rect3
                100
                height: 100
                color: "yellow"
                Layout.fillWidth: true
            }
        }










    }


}
main.qml

ColumnLayout:

类似... 

QML  常用控件:

1,行编辑:

TextInput ,TextField

2,文本块:

TextEdit,TextArea

3,互斥分组:

ExclusiveGroup 

4,RadioButton:

单选按钮

5,CheckBox:

多选框

6,GroupBox:

分组框

7,ComboBox:

下拉框

8,ProgressBar:

进度条

9,TabView:

点击标签会进入对应界面,选项卡控件

10,Slider:

滑块控件

11,Flickable:

Flickable提供一个较小的视窗来显示一个较大的内容给用户,并且用户可以对改内容进行拖拽和轻拂

12,Screen:

它是显示Item 的那个屏幕,它提供了一些只读属性来描述屏幕参数。

Canvas 画布:

Canvas 是Item 的派生类,

1,画布:

    Canvas{
         300
        height: 200
    }
View Code

这即是一块画布,

2,画师:

画师是Context2D ,QT帮助文档直接搜索Context2D ,

Canvas{
     300
    height: 200
    onPaint: {
        var ctx = getContext("2d");  // 在QML 中,一块画布只有一个画师
    }
}
View Code

3,画笔:
关于画笔的属性设置,在Contex2D对象 上都有,有笔的粗细(lineWidth),笔的颜色(strokeStyle)之类的

4,画刷:

画刷是用来填充画笔勾勒出的区域的,属性是fillStyle,

坐标系:

在2D世界,原点位于屏幕左上角(0,0), 向右是x 轴,向下是y轴。

图元:

基本的图元有线,弧,矩形,曲线,文本,图片,

小试牛刀:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Canvas{
         800
        height: 600
        onPaint: {
            var ctx = getContext("2d");  // 在QML 中,一块画布只有一个画师
            ctx.lineWidth = 2;
            ctx.strokeStyle = "red"; // 画笔颜色
            ctx.fillStyle = "blue"; // 画刷 颜色


            ctx.beginPath();
            ctx.rect(60,50,120,80);
            ctx.fill();
            ctx.stroke(); // 使用stroke() 结束路径的绘制

            var gradient = ctx.createRadialGradient(200,140,40,280,220,20);
            gradient.addColorStop(0.0,Qt.rgba(1,0,0,1.0));
            gradient.addColorStop(1.0,Qt.rgba(0,0,1,1.0));
            ctx.fillStyle = gradient;
            ctx.beginPath();

            ctx.rect(200,140,80,80);
            ctx.fill();

            ctx.stroke();

        }
    }

}
main.qml
import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Canvas{
         800
        height: 600
        onPaint: {
            var ctx = getContext("2d");  // 在QML 中,一块画布只有一个画师
            ctx.lineWidth = 2;
            ctx.strokeStyle = "red"; // 画笔颜色
            ctx.fillStyle = "blue"; // 画刷 颜色
            ctx.beginPath();

            ctx.moveTo(100,80); // 移动到 100,80
            ctx.lineTo(100,200); // 从当前位置到(x,y)点绘制一条直线
            ctx.lineTo(300,200);
            ctx.closePath(); // 结束当前的路径,从路径终点到起点绘制一条直线来封闭路径

            ctx.fill();
            ctx.stroke(); // 使用stroke() 结束路径的绘制

        }
    }

}
main.qml
import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Canvas{
         800
        height: 600
        onPaint: {
            var ctx = getContext("2d");  // 在QML 中,一块画布只有一个画师
            ctx.lineWidth = 2;
            ctx.strokeStyle = "red"; // 画笔颜色
            ctx.fillStyle = "blue"; // 画刷 颜色
            ctx.font = "42px sans-serif";
            ctx.beginPath();

            ctx.moveTo(4,4);
            ctx.bezierCurveTo(0,height - 1,width -1 ,height/2,width/4,height/4);
            ctx.lineTo(width/2,height/4);
            ctx.arc(width*5/8,height/4,width/8,Math.PI,0,false);
            ctx.ellipse(width*11/16,height/4,width/8,height/4);
            ctx.lineTo(width/2,height*7/8);
            ctx.text("Hello World",width/4,height*7/8);

            ctx.fill();
            ctx.stroke(); // 使用stroke() 结束路径的绘制

        }
    }

}
View Code

与文本相关:

有三个方法:fillText()  ,strokeText(),text()

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Canvas{
         800
        height: 600
        onPaint: {
            var ctx = getContext("2d");  // 在QML 中,一块画布只有一个画师
            ctx.lineWidth = 2;
            ctx.strokeStyle = "red"; // 画笔颜色
            ctx.font = "42px sans-serif";
            ctx.fillStyle = "green"; // 画刷颜色

            //1
            ctx.beginPath();
            ctx.text("Hello World -fill",50,50);
            ctx.fill();

            //2
            ctx.fillText("Hello World -fillText",50,150);

            //3
            ctx.beginPath();
            ctx.text("Hello World -stroke",50,200);
            ctx.stroke();

            //4
            ctx.strokeText("Hello World -strokeText",50,250);

            //5
            ctx.beginPath();
            ctx.text("Hello World -fill -stroke",50,300);
            ctx.fill();
            ctx.stroke();


        }
    }

}
View Code

绘制图片:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Canvas{
         800
        height: 600
        property var imgSrc:"images/rocket.png"
        onPaint: {
            var ctx = getContext("2d");
            //1
            ctx.drawImage(imgSrc,100,100);

        }
        Component.onCompleted: loadImage(imgSrc); // loadImage 会异步加载图片,当图片加载完成时会发射imageLoaded 信号
        onImageLoaded: {
            requestPaint(); // 重新绘制 Canvas  画布
        }


    }

}
View Code

变换:

平移(translate),旋转(rotate),缩放(scale)错切(shear),

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Canvas{
         800
        height: 600
        property var imgSrc:"images/rocket.png"
        onPaint: {
            var ctx = getContext("2d");
            ctx.lineWidth = 2;
            ctx.strokeStyle = "blue";
            ctx.fillStyle = "purple";

            ctx.save();
            ctx.beginPath();
            ctx.translate(width/2,height/2);
            ctx.arc(0,0,30,0,Math.PI*2);
            ctx.arc(0,0,50,0,Math.PI*2);
            ctx.arc(0,0,70,0,Math.PI*2);
            ctx.arc(0,0,90,0,Math.PI*2);
            ctx.stroke();
            ctx.restore(); //  恢复到save() 之前的状态

            ctx.save();
            ctx.translate(width/2,30);
            ctx.font = "42px sans-serif";
            ctx.textAlign="center";
            ctx.fillText("concentric circles",0,0);
            ctx.restore();

        }



    }

}
View Code

Note :restore()  和 save()结合使用,

裁剪:

Context2D 的clip()  方法,让我们能够根据当前路径包围的区域来裁剪。

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Canvas{
         800
        height: 600
        property var imgSrc:"images/1.jpg"
        onPaint: {
            var ctx = getContext("2d");
            ctx.lineWidth = 2;
            ctx.strokeStyle = "blue";
            ctx.fillStyle = Qt.rgba(0.3,0.5,0.7,0.3);

            ctx.save();
            ctx.beginPath();
            ctx.arc(180,150,80,0,Math.PI*2,true);
            ctx.closePath();
            ctx.clip(); // 裁剪
            ctx.drawImage(imgSrc,0,0);
            ctx.stroke();
            ctx.fill();

            ctx.rotate(Math.PI/5);
            ctx.font = "italic bold 32px serif";
            ctx.fillStyle = "red"; // 字体填充颜色
            ctx.fillText("Hello World,Wosdfjklf ",100,70);
            ctx.restore();

        }
        Component.onCompleted: loadImage(imgSrc);
        onImageLoaded: requestPaint();
    }

}
View Code

图像合成:

globalCompositeOperation 

QML 动画:

基本动画对象:

PropertyAnimation: 通过改变各种类型的property 来产生动画

NumberAnimation:  PropertyAnimation 的子类,专门改变数字类型的property来产生动画,效率比PropertyAnimation 好,

ColorAnimaiton :  PropertyAnimation 的子类,专门改变color 类型的property 来产生动画,效率比PropertyAnimation 好,

RotationAnimaiton :  PropertyAnimation 的子类,专门改变rotation 值来产生动画,效率比PropertyAnimation 好,另外还提供旋转方向等附加属性,

Vector3dAnimation:  PropertyAnimation 的子类,当一个Vector3d值 发生变化时使用。

PathAnimation: 让对象沿一个给定的方向移动

SmoothedAnimation: 允许一个property 跟踪一个值,产生平滑动画

SpringAnimation允许一个property 跟踪一个值,动画效果类似于弹簧运动,

分组动画对象:

SequentialAnimation: 顺序执行一系列动画

ParallAnimation :  并行执行一系列动画

动画搭档:

State,它是Item的状态,不同状态对应不同的界面效果和业务逻辑。

Transition, 过渡,它用来衔接不同状态,使状态变化过程平滑。

协同动画元素:

Behavior : 它为Item 的property 变化绑定一个默认的动画对象。

ParentAnimation, 当改变一个Item的parent的时候使用,使得从旧parent到新parent的过程更平滑,通常与State,Transition,ParentChange联合使用。

AnchorAnimation: 当改变一个Item 的 anchor的时候使用,通常与State,Transition,AnchorChange联合使用。

PauseAnimation:如果在动画过程插入它,可以将动画过程暂停一段时间。

PropertyAction: 动画执行过程立即改变某个属性。

ScriptAction:动画执行过程运行一段JS脚本。

测试代码:

PropertyAnimation定义的三种方式:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
         50
        height: 50
        anchors.centerIn: parent
        color: "blue"
        MouseArea{
            anchors.fill: parent
            onClicked: animation.running = true;
        }
    }
    Rectangle{
        id:rect2
         50
        height: 50
        color: "red"
    }
    PropertyAnimation{
        id:animation
        targets: [rect,rect2]
        properties: "width,height"
        to:150
        duration: 1000;
    }







}
View Code
import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
         50
        height: 50
        anchors.centerIn: parent
        color: "blue"
        MouseArea{
            anchors.fill: parent
            onClicked: PropertyAnimation{ // 在信号处理器中直接使用动画
                id:animation
                target: rect
                properties: "width,height"
                to:150
                duration: 1000;
            }
        }
    }








}
在信号处理器中直接使用动画
import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
         50
        height: 50
        anchors.centerIn: parent
        color: "blue"
        MouseArea{
            id:mouseArea
            anchors.fill: parent
        }
        PropertyAnimation on width{ // Animation on <property > 这种语法格式 可以将一个动画和一个属性关联起来
            to:150
            duration: 1000
            running: {
                return mouseArea.pressed
            }
        }


    }








}
Animation on 语法格式

Animation 的started() 和 stopped() 信号:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
         50
        height: 150
        anchors.centerIn: parent
        color: "blue"
        property var animation;
        PropertyAnimation{
            id:toSquare
            target: rect
            property: "width"
            to:150
            duration: 1000
            onStarted: {
                rect.animation = toSquare;
                rect.color = "red";
            }
            onStopped: {
                rect.color = "blue";
            }
        }
        PropertyAnimation{
            id:toRect
            target: rect
            property: "width"
            to:50
            duration: 1000
            onStarted: {
                rect.animation = toRect;
                rect.color = "red";
            }
            onStopped: {
                rect.color = "blue";
            }
        }

        MouseArea{
            id:mouseArea
            anchors.fill: parent
            onClicked: {
                if(rect.animation == toRect || rect.animation == undefined){
                    toSquare.start();
                }else{
                    toRect.start();
                }
            }


        }



    }








}
View Code

NumberAnimation:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
         50
        height: 150
        anchors.centerIn: parent
        color: "blue"

        NumberAnimation {
            id:numAni
            target: rect
            property: "width"
            to:150
            duration: 200
            easing.type: Easing.InOutQuad
        }

        MouseArea{
            id:mouseArea
            anchors.fill: parent
            onClicked: {
                numAni.running = true;
            }

        }



    }








}
View Code

ColorAnimation:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
         50
        height: 150
        anchors.centerIn: parent
        color: "blue"

        MouseArea{
            id:mouseArea
            anchors.fill: parent
            onClicked: ColorAnimation {
                target: rect
                property: "color"
                to: "green"
                duration: 200
            }

        }



    }








}
View Code

RotationAnimation:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
         50
        height: 150
        anchors.centerIn: parent
        color: "blue"
//        transformOrigin: Item.TopRight
        Text {
            id: txt
            anchors.fill: parent
            text: qsTr("text")
        }


        MouseArea{
            id:mouseArea
            anchors.fill: parent
            onClicked: RotationAnimation{
                target: rect
                to:90
                duration: 1000
                direction: RotationAnimation.Clockwise // 顺时针

            }

        }



    }








}
View Code

PathAnimation:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Canvas{  // 画一个半圆
         400
        height: 240

        onPaint: {
            var ctx = getContext("2d");
            ctx.lineWidth = 4;
            ctx.strokeStyle = "red";
            ctx.beginPath();
            ctx.arc(200,0,160,Math.PI*2,0,false);
            ctx.stroke();
        }

    }


    Rectangle{
        id:rect
         40
        height: 40
        color: "blue"
        x:20
        y:0


        MouseArea{
            id:mouseArea
            anchors.fill:parent
            onClicked: pathAnim.start();
        }
        PathAnimation{
            id:pathAnim
            target: rect
            duration: 6000
            anchorPoint: "20,20"// rect 的center

            orientation: PathAnimation.BottomFirst
            orientationEntryDuration: 200  // 调整初始姿态的时间
            endRotation: 0 // 最后的角度 :0
            orientationExitDuration: 200  // 调整终止时姿态的时间
            easing.type: Easing.InOutCubic

            path: Path{
                startX: 40
                startY: 0
                PathArc{
                    x:360 // 终点(360,0)
                    y:0
                    useLargeArc: true; // 采用 优弧(较大)模式
                    radiusX: 160  // 椭圆的两个半轴
                    radiusY: 160
                    direction: PathArc.Counterclockwise // 逆时针
                }
            }

        }




    }








}
View Code

SmoothedAnimation:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
         40
        height: 40
        color: "red"
        x:20
        y:20

        SmoothedAnimation{  // SmoothedAnimation默认采用 easing.type 为InOutQuad
            id:smoothAni1
            target: rect
            property: "x"
            duration: 1000
            velocity: -1   //速率 默认速率是200units/秒, -1 为禁用速率
                // 如果duration和 velocity同时设置,那么会使用速率计算出一个时间, 它和duration的较短者会被采用。
        }
        SmoothedAnimation{
            id:smoothAni2
            target: rect
            property: "y"
            velocity: 100
        }
    }
    MouseArea{
        anchors.fill: parent
        onClicked: {
            smoothAni1.from = rect.x;
            smoothAni1.to = mouse.x + 4;
            smoothAni1.start();
            smoothAni2.from = rect.y;
            smoothAni2.to = mouse.y + 4;
            smoothAni2.start();
        }
    }







}
View Code

SpringAnimation:

可以用来模拟弹簧的震荡行为,

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
         40
        height: 40
        color: "red"
        x:20
        y:20
    }
    SpringAnimation{
        id:springAni1
        target: rect
        property: "x"
        spring: 3 // 加速度 0-5 有意义 默认为0
        damping: 0.06 //衰减系数0-1.0 有意义, 值越大会越快平复
        epsilon: 0.25 //允许设定一个最接近0 的阈值代表0 ,如果是基于像素动画,建议0.25 ,如果是基于scale动画,建议0.005 。 默认为0.01 ,调整epsilon 可能会有一定的性能提升
    }

    SpringAnimation{
        id:springAni2
        target: rect
        property: "y"
        spring: 3
        damping: 0.06
        epsilon: 0.25
    }

    MouseArea{
        anchors.fill: parent
        onClicked: {
            springAni1.from = rect.x;
            springAni1.to = mouse.x - 20;
            springAni1.start();

            springAni2.from = rect.y;
            springAni2.to = mouse.y - 20;
            springAni2.start();

        }
    }






}
View Code

组合动画:

State:

在QML中,状态是定义在State类型中的一系列属性配置。不同的配置可能有不同的作用:

1,显示一些UI组件,隐藏另一些

2,想用户呈现不同的操作和功能

3,启动,暂停,停止动画

4,在某种新的状态下执行某些脚本

5,改变某个特定Item的property的值

6,显示一个不同的view或screen 

等等...

代码:

import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
         360
        height: 240
        color: "#eee"
        Text {
            id: centerTxt
            text: qsTr("Just a text!")
            anchors.centerIn: parent
            font.pixelSize: 24
            MouseArea{
                id:mouseArea
                anchors.fill: parent

                onPressed: {
                    centerTxt.state = "blueText";
                }
                onReleased: {
                    centerTxt.state = "redText";
                }
            }
            state:"redText"
            states: [
                State {
                    name: "redText"
                    changes: [
                        PropertyChanges {
                            target: centerTxt
                            color:"red"
                        }
                    ]
                },
                State {
                    name: "blueText"
                    PropertyChanges {
                        target: centerTxt
                        color:"blue"
                    }
                }
            ]
        }

    }






}
使用State 变换文本
import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.12


Window {
    id: root
    visible: true
    title: qsTr("Hello World")
     800
    height: 600

    Rectangle{
        id:rect
         360
        height: 240
        color: "#eee"
        Text {
            id: centerTxt
            text: qsTr("Just a text!")
            anchors.centerIn: parent
            font.pixelSize: 24
            MouseArea{
                id:mouseArea
                anchors.fill: parent
                acceptedButtons: Qt.LeftButton | Qt.RightButton
            }
            state:"redText"
            states: [
                State {
                    name: "redText"
                    when:mouseArea.pressedButtons === Qt.RightButton
                    changes: [
                        PropertyChanges {
                            target: centerTxt
                            color:"red"
                        },
                        PropertyChanges {
                            target: centerTxt
                            font.bold:true
                            font.italic: true
                        }
                    ]
                },
                State {
                    name: "blueText"
                    when: mouseArea.pressed
                    PropertyChanges {
                        target: centerTxt
                        color:"blue"
                        font.pixelSize: 48;
                    }
                }
            ]
        }

    }






}
点击左右鼠标键,产生不同效果

C++ 与 QML 混合编程:

在QML中使用c++ 类和对象:

要想将一个类或对象导出到QML,前提条件是:

1,从QObject 或 QObject 的派生类继承  

2,使用Q_OBJECT 宏  

省略...

在QML中使用c++ 类和对象:

原文地址:https://www.cnblogs.com/zach0812/p/13296018.html