《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")
    width: 800
    height: 600

    Button {
        id:btn
        x: 0
        y: 62
        text: "Quit2"
        style:ButtonStyle {
            background: Rectangle {
                implicitWidth: 100
                implicitHeight: 25
                border.width: 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")
    width: 800
    height: 600


    Button {  // 會默認放到   data 列表中
        id:btn
        text: "Quit"
    }
    Window {
        id: root2
        visible: true
        title: qsTr("Hello World")
        width: 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")
    width: 800
    height: 600

    Rectangle{
        width: 500
        height: 500
        border.color: Qt.lighter("purple")
        border.width: 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")
    width: 800
    height: 600
    color: "cyan"

    Rectangle{
        id:rect1
        color: "purple"
        width: 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")
    width: 800
    height: 600
    color: "cyan"

    Image {
        id: img1
        width: 100
        height: 100
        source: "images/1.gif" // 不能顯示GIF,因為Image只能顯示靜態圖片
    }
    // 可以使用 AnimatedImage 顯示動態圖片
    AnimatedImage {
        id:aniImg1
        x:100
        y:100
        width: 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")
    width: 800
    height: 600
    color: "cyan"

    Rectangle{
        width: 500
        height: 500
        border.color: "red"
        border.width: 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")
    width: 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")
    width: 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")
    width: 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
            width: 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")
    width: 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
            width: 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")
    width: 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
    width: 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")
    width: 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
    width: 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")
    width: 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"; width: 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")
    width: 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"; width: 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")
    width: 800
    height: 600

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

        GridLayout{
            width: 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
                width:100
                height: 100
                color: "purple"
                Layout.columnSpan: 2
                Layout.rowSpan: 2
                Layout.fillWidth: true

            }

            Rectangle{
                id:rect2
                width:100
                height: 100
                color: "cyan"
            }
            Rectangle{
                id:rect3
                width: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")
    width: 800
    height: 600

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

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

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

            }

            Rectangle{
                id:rect2
                width:100
                height: 100
                color: "cyan"
            }
            Rectangle{
                id:rect3
                width: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{
        width: 300
        height: 200
    }
View Code

這即是一塊畫布,

 

2,畫師:

畫師是Context2D ,QT幫助文檔直接搜索Context2D ,

Canvas{
    width: 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")
    width: 800
    height: 600

    Canvas{
        width: 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")
    width: 800
    height: 600

    Canvas{
        width: 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")
    width: 800
    height: 600

    Canvas{
        width: 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")
    width: 800
    height: 600

    Canvas{
        width: 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")
    width: 800
    height: 600

    Canvas{
        width: 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")
    width: 800
    height: 600

    Canvas{
        width: 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")
    width: 800
    height: 600

    Canvas{
        width: 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")
    width: 800
    height: 600

    Rectangle{
        id:rect
        width: 50
        height: 50
        anchors.centerIn: parent
        color: "blue"
        MouseArea{
            anchors.fill: parent
            onClicked: animation.running = true;
        }
    }
    Rectangle{
        id:rect2
        width: 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")
    width: 800
    height: 600

    Rectangle{
        id:rect
        width: 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")
    width: 800
    height: 600

    Rectangle{
        id:rect
        width: 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")
    width: 800
    height: 600

    Rectangle{
        id:rect
        width: 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")
    width: 800
    height: 600

    Rectangle{
        id:rect
        width: 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")
    width: 800
    height: 600

    Rectangle{
        id:rect
        width: 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")
    width: 800
    height: 600

    Rectangle{
        id:rect
        width: 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")
    width: 800
    height: 600

    Canvas{  // 畫一個半圓
        width: 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
        width: 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")
    width: 800
    height: 600

    Rectangle{
        id:rect
        width: 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")
    width: 800
    height: 600

    Rectangle{
        id:rect
        width: 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")
    width: 800
    height: 600

    Rectangle{
        id:rect
        width: 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")
    width: 800
    height: 600

    Rectangle{
        id:rect
        width: 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++ 類和對象:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM