1. 程式人生 > >Qt Quick之StackView具體解釋(1)

Qt Quick之StackView具體解釋(1)

left 記錄 內部 變化 原創 focus filo 郵箱 sta

Qt Quick中有個StackView。我在《Qt Quick核心編程》一書中沒有講到。近期有人問起,趁機學習了一下,把它的基本使用方法記錄下來。

我準備分兩次來講。第一次講主要的使用方法。包含StackView的適用場景、基本屬性和方法的使用方法。第二次講一些略微復雜點的東西,比方被StackView管理的view的生命周期、delegate定制、查找等。

演示樣例會用到動態創建組建,能夠參考我之前的文章“Qt Quick 組件與對象動態創建具體解釋”。也會用到錨布局。參考“Qt Quick 布局介紹”。還會用到Button、Rectangle、MouseArea、Text等基本元素,請參考《Qt Quick核心編程

》一書。

StackView介紹

StackView實現了一個棧式的導航。“”大家都知道是怎麽回事兒,就是一種數據結構,先進後出(FILO),支持pop、push等操作。StackView用於棧相似的行為方式管理一系列的View(頁面或視圖),這些View之間可能有內在聯系,依據業務須要,能夠一級一級向深處的跳轉。當前的View上發生點兒什麽事兒,就可能會產生一個新的View或返回之前的頁面。

舉兩個簡單的場景。

比方註冊賬號這個場景,有一種做法是分幾個步驟,比方第一步先讓你輸入username、password,你點擊下一步之後呢,會出現新的頁面。接著讓你輸入姓名、愛好、郵箱、社交方式等。

比方你在某個招聘站點提交簡歷,先是填寫基本信息,如姓名、畢業院校、聯系方式、求職意向等,然後下一步,就讓你加入工作經驗……一路Next下去就可以。講到這裏你能夠看看我之前寫的一篇文章。史上最全的程序猿求職渠道總結

StackView是FocusScope的子類,FocusScope是Item的子類。從這個繼承關系來看,StackView要作為一個Window的孩子(孩子的孩子也能夠。孩子的孩子的孩子也能夠……)來使用。當然假設你用QQuickView來載入main.qml的話,StackView也能夠作為main.qml的根節點,不必嵌套在一個Window裏。

StackView有幾個屬性:

  • busy 指示StackView是否正在應用過渡動畫。為true時表示正在應用動畫。能夠通過屬性變化信號處理器onBusyChanged來響應busy屬性變化,結合我們的業務需求來做一些處理,比方在動畫期間禁止用戶點擊。

  • currentItem 指向棧頂的View(Item),可能為空。
  • delegate 用於定制頁面切換時的過渡動畫。
  • depth 棧的深度,StackView中沒有子頁面時。depth為0。有一個子頁面時。depth為1……
  • initialItem 初始的View(Item)。

    我們能夠通過這個屬性來指定StackView管理的第一個頁面(View),假設你在初始化時給initalItem賦值,效果就相當於我們在Component.onCompleted信號處理器中調用 push(yourItem)。假設你不顯式給initalItem賦值,當第一個頁面被push進StackView時。這個屬性也會被自己主動賦值。

StackView有幾個方法:

  • clear()。顧名思義。幹掉StackView管理的全部頁面
  • pop(item),出棧操作。無參調用pop時,講棧頂的頁面彈出。假設帶參數,則將參數指定的頁面之後的全部頁面都彈出。舉個樣例吧,如今棧內頁面時醬紫的,[A,B,C,D,E],pop()調用後。就變為[A,B,C,D]。你再調用pop(B),就會變成[A,B]。
  • push(item),入棧操作,參數是Item。將一個頁面壓入StackView。這個頁面(Item)通常是動態創建的。

    待會兒我們的演示樣例能夠看到。有一個特別的使用方法,能夠替換棧頂元素,比方你的棧是[A,B,C,D],push(E, replace),就會用E替換棧頂的D,棧就會變為[A,B,C,E]。關於push,另一些其他使用方法。參考Qt幫助吧。

  • find(func, onlySearchLoadedItems),查找StackView管理的某個頁面。

    find將對棧內的每一個頁面應用func方法,當func返回true時。表示找到了,查找過程就會停止,然後find會返回找到的那個Item。

  • completeTransition(),馬上結束過渡動畫。

再啰嗦幾句吧。

StackView本身事實上是一個正常的Item。這從它的類繼承關系能夠看出來。

所以呢,你能夠指定它的大小(width、height),也能夠使用anchors等布局。StackView管理的頁面,都會作為StackView的孩子,這些子View們,默認會充滿StackView的可用區域,我們不能使用anchors來布局子頁面,假如你為子View使用了anchors,那頁面切換時的動畫效果就會失效。

另一點,指定子頁面的大小(width、height)也無論用。所以。省事兒啦。

StackView演示樣例

設計了一個很easy的演示樣例,效果例如以下圖所看到的:

技術分享

我們看到。在上面的GIF中,點擊Nextbutton會新創建一個頁面並將這個頁面加入到StackView中,頁面切換時有一個動畫效果。這個動畫效果是StackView提供的默認效果。假設我們想改變它。就能夠通過delegate屬性來定制。

全部代碼在這裏了:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2

Window {
    title: "StackViewDemo";
    width: 480;
    height: 320;
    visible: true;

    StackView {
        id: stack;
        anchors.centerIn: parent;
        width: 600;
        height: 300;
        property var home: null;

        Text {
            text: "Click to create first page";
            font.pointSize: 14;
            font.bold: true;
            color: "blue";
            anchors.centerIn: parent;
            MouseArea {
                anchors.fill: parent;
                onClicked: if(stack.depth == 0)stack.push(page);
            }
        }
    }

    Component {
        id: page;

        Rectangle {
            color: Qt.rgba(stack.depth*0.1, stack.depth*0.2, stack.depth*0.3);

            Text {
                anchors.centerIn: parent;
                text: "depth - " + stack.depth;
                font.pointSize: 24;
                font.bold: true;
                color: stack.depth <= 4 ? Qt.lighter(parent.color) : Qt.darker(parent.color);
            }

            Button {
                id: next;
                anchors.right: parent.right;
                anchors.bottom: parent.bottom;
                anchors.margins: 8;
                text: "Next";
                width: 70;
                height: 30;
                onClicked: {
                    if(stack.depth < 8) stack.push(page);
                }
            }

            Button {
                id: back;
                anchors.right: next.left;
                anchors.top: next.top;
                anchors.rightMargin: 8;
                text: "Back";
                width: 70;
                height: 30;
                onClicked: {
                    if(stack.depth > 0) stack.pop();
                }
            }

            Button {
                id: home;
                anchors.right: back.left;
                anchors.top: next.top;
                anchors.rightMargin: 8;
                text: "Home";
                width: 70;
                height: 30;
                onClicked: {
                    if(stack.depth > 0)stack.pop(stack.initialItem);
                }
            }

            Button {
                id: clear;
                anchors.right: home.left;
                anchors.top: next.top;
                anchors.rightMargin: 8;
                text: "Clear";
                width: 70;
                height: 30;
                onClicked: {
                    if(stack.depth > 0)stack.clear();
                }
            }
        }
    }
}

簡單解釋一下上面的代碼。id為stack的StackView,內部放了一個Text元素,點擊時創建第一個頁面。頁面由內嵌在main.qml中的Component提供。

id為page的組件,頂層元素是個Rectangle對象,顏色由StackView的depth屬性決定。這個Rectangle內部,中間放了一個Text。底部放了Clear、Home、Back、Next幾個button,在這些button的onClicked信號處理器中,調用了StackView的clear、pop、push等方法。

你能夠使用qmlscene來載入演示樣例qml文檔,也能夠通過Qt Creator創建一個Qt Quick App來查看效果。建議使用Qt SDK 5.3.0及以上版本號。

OK,這次就先到這裏了。下次我們來講StackView管理的頁面(View)的生命周期、查找View、動畫定制等內容。


很多其他Qt Quick文章請參考我的Qt Quick專欄,想系統學些Qt Quick(QML),請閱讀《Qt Quick核心編程》。


我開通了微信訂閱號“程序視界”,關註就可以第一時間看到我的原創文章以及我推薦的精彩文章:

技術分享

Qt Quick之StackView具體解釋(1)