Qt QML Component 學習筆記

簡介  

  Component是Qt封裝好的、只暴露必要接口的QML類型,能夠重複利用。一個QML組件就像一個黑盒子,它經過屬性、信號、函數和外部世界交互。編程

  一個Component既能夠定義在獨立的QML文件(.qml爲後綴的文件)中,也能夠嵌入到其餘的QML文件中來定義。那麼這兩種方式分別適用於什麼場景呢?這裏有一個原則能夠幫助咱們去選擇Component的定義方式:若是一個Component比較小且只在某個QML文件中使用,或者說一個Component從邏輯上來看屬於某個QML文檔,那麼就能夠採用嵌入的方式來定義該Component;若是這個Component有不少地方能夠用到,也就是說複用率比較高,那麼就能夠採用定義在獨立的QML文件中的方式。下面說明一下這兩種實現Component方式的差異:函數

  • 嵌入式定義Component:

   要在一個QML文件中嵌入Component的定義,須要使用Component對象。ui

  定義一個Component與定義一個QML文件相似,Component只能包含一個頂層Item,並且在這個Item以外不能定義任何數據,除了id。 在頂層Item以內,則能夠包含更多的子元素來協同工做,最終造成一個具備特定功能的組件。this

  Component一般用來給一個View提供圖形化組件,好比ListVIew::delegate屬性就須要一個Component來指定如何顯示列表的每個項,又好比ButtonStyle::background屬性也須要一個Component來指定如何繪製Button的背景。  spa

  Component不是Item的派生類,而是從QQmlComponent繼承而來的,雖然它經過本身的頂層Item爲其餘的view提供可視化組件,但它自己是不可見元素。你能夠這麼理解:你定義的組件是一個新的類型,他必須被實例化之後才能顯示。而要實例化一個嵌入在QML文件中定義的Component,則能夠經過Loader。code

  • 在單獨文件中定義Component:

  不少時候咱們把一個Component單獨定義在一個QML文件中,好比Qt Qucik提供的BusyIndicator空間,其實就是在BusyIndicator中定義一個組件(BusyIndicator.qml):對象

Control {
    id: indicator

    /*! \qmlproperty bool BusyIndicator::running

    This property holds whether the busy indicator is currently indicating
    activity.

    \note The indicator is only visible when this property is set to \c true.

    The default value is \c true.
    */
    property bool running: true

    Accessible.role: Accessible.Indicator
    Accessible.name: "busy"

    style: Settings.styleComponent(Settings.style, "BusyIndicatorStyle.qml", indicator)
}

  能夠看到BusyIndicator的代碼很是簡單,只是給Control元素(Qt Quick定義的私有元素,用做其餘控件的基類,如ComboBox、BusyIndicator等)增長了一個屬性,設置了幾個值而已。blog

  BusyIndicator.qml文件中的頂層Item是Control,而咱們使用時倒是以BusyIndicator爲組件名(類名)。這是定義Component的一個約定:組件名必須和QML文件名一致,且組件名的首字母必須是大寫的。Qt Quick提供的多數基本元素和特性,均可以在定義組件時使用 。繼承

  例子:在一個單獨的QMl文件中定義顏色選擇組件ColorPicker,對應QML文件爲ColorPicker.qml,能夠在其餘的QMl文件中使用Cololr{...}來建立ColorPicker的實例。接口

import QtQuick 2.6

Rectangle {
    id: colorPicker
    width: 50
    height: 30
    signal colorPicked(color clr);

    function configureBorder() {
        colorPicker.border.width = colorPicker.focus ? 2 : 0;
        colorPicker.border.color = colorPicker.focus ? "#90D750" : "#808080";
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            colorPicker.colorPicked(colorPicker.color);
            mouse.accepted = true;
            colorPicker.focus = true;
        }
    }

    Keys.onReturnPressed: {  // 對應Enter鍵
        console.log("ColorPicker:onReturnPressed");
        colorPicker.colorPicked(colorPicker.color);
        event.accepted = true;
    }

    Keys.onSpacePressed: {  // 對應Space鍵
        console.log("ColorPicker:onSpacePressed");
        colorPicker.colorPicked(colorPicker.color);
        event.accepted = true;
    }

    onFocusChanged: {
        console.log("ColorPicker:onFocusChanged");
        configureBorder();
    }

    Component.onCompleted: {
        console.log("ColorPicker:onCompleted");
        configureBorder();
    }
}

  在單獨文件中定義Component,與嵌入式定義有明顯的不一樣:Component對象不見了,是由於在單獨文件中定義組件,不須要Component對象,只有在其餘QML文件中嵌入式定義組件時才須要Component對象。

  main.qml內容:

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

Window {
    visible: true
    width: 320
    height: 240
    title: qsTr("Component")

    Rectangle {
        width: parent.width
        height: parent.height
        color: "#EEEEEE"

        Text {
            id: coloredText
            anchors.centerIn: parent
            anchors.top: parent.top
            anchors.topMargin: 4
            text: "ColorPicker"
            font.pixelSize: 32
        }

        function setTextColor(clr) {
            coloredText.color = clr;
        }

        ColorPicker {
            id: redColor
            color: "red"
            focus: true
            width: parent.width / 3 - 4
            anchors.left: parent.left
            anchors.leftMargin: 4
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 4

            KeyNavigation.right: blueColor
            KeyNavigation.tab: blueColor
            onColorPicked: {
                coloredText.color = clr;
            }
        }


        ColorPicker {
            id: blueColor
            color: "blue"
            width: parent.width / 3 - 4
            anchors.left: redColor.right
            anchors.leftMargin: 4
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 4

            KeyNavigation.left: redColor
            KeyNavigation.right: pinkColor
            KeyNavigation.tab: pinkColor
        }

        ColorPicker {
            id: pinkColor
            color: "pink"
            width: parent.width / 3 - 8
            anchors.left: blueColor.right
            anchors.leftMargin: 4
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 4

            KeyNavigation.left: blueColor
            KeyNavigation.tab: redColor
        }

        Component.onCompleted: {
            blueColor.colorPicked.connect(setTextColor);
            pinkColor.colorPicked.connect(setTextColor);
        }
    }
}

 

《Qt Quick核心編程》

相關文章
相關標籤/搜索