<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                #(86):視圖代理 與?[Qt model/view 架構](http://www.devbean.net/2013/01/qt-study-road-2-model-view/)類似,在自定義用戶界面中,代理扮演著重要的角色。模型中的每一個數據項都要通過一個代理向用戶展示,事實上,用戶看到的可視部分就是代理。 每一個代理都可以訪問一系列屬性和附加屬性。這些屬性及附加屬性中,有些來自于數據模型,有些則來自于視圖。前者為代理提供了每一個數據項的數據信息;后者則是有關視圖的狀態信息。 代理中最常用到的是來自于視圖的附加屬性`ListView.isCurrentItem`和`ListView.view`。前者是一個布爾值,用于表示代理所代表的數據項是不是視圖所展示的當前數據項;后者則是一個只讀屬性,表示該代理所屬于的視圖。通過訪問視圖的相關數據,我們就可以創建通用的可復用的代理,用于適配視圖的大小和展示特性。下面的例子展示了每一個代理的寬度都綁定到視圖的寬度,而代理的背景色則根據附加屬性`ListView.isCurrentItem`的不同而有所不同。 ~~~ import QtQuick 2.0 Rectangle { width: 120 height: 300 gradient: Gradient { GradientStop { position: 0.0; color: "#f6f6f6" } GradientStop { position: 1.0; color: "#d7d7d7" } } ListView { anchors.fill: parent anchors.margins: 20 clip: true model: 100 delegate: numberDelegate spacing: 5 focus: true } Component { id: numberDelegate Rectangle { width: ListView.view.width height: 40 color: ListView.isCurrentItem?"#157efb":"#53d769" border.color: Qt.lighter(color, 1.1) Text { anchors.centerIn: parent font.pixelSize: 10 text: index } } } } ~~~ 代碼運行結果如下圖所示: [![](https://box.kancloud.cn/2015-12-29_5682328a72a82.png)](http://files.devbean.net/images/2015/08/delegate.png) 如果該模型的每一個數據項都關聯一個動作,例如,響應對該數據項的點擊操作,那么,這種功能就應該是每一個代理的一部分。這將事件管理從視圖分離出來。視圖主要處理的是各個子視圖之間的導航、切換,而代理則是對一個特定的數據項的事件進行處理。完成這一功能最常用的方法是,為每一個視圖創建一個`MouseArea`,然后響應其`onClicked`信號。我們會在后面看到這種實現的示例。 ## 為增加、移除項添加動畫 很多情況下,一個視圖中的數據項并不是固定不變的,而是需要動態地增加、移除。數據項的增加、移除,其實是底層模型的修改的相關反應。此時,添加動畫效果往往是個不錯的選擇,可以讓用戶清晰地明白究竟是哪些數據發生了改變。 為了達到這一目的,QML 為每個代理提供了兩個信號,`onAdd`和`onRemove`,只要將這些信號與動畫效果關聯起來即可。 下面的例子演示了為動態修改`ListModel`增加動畫效果。在屏幕下方有一個用于新增數據項的按鈕。點擊該按鈕,會通過調用`append`函數向模型增加一個數據項。這將觸發視圖創建一個新的代理,并且發出`GridView.onAdd`信號。該信號關聯了一個`SequentialAnimation`類型的動畫,利用`scale`屬性的變化,將代理縮放到視圖。當視圖中的一個數據項被點擊時,該項會通過調用視圖的`remove`函數被移除。這會發出`GridView.onRemove`信號,觸發另一個`SequentialAnimation`類型的動畫。不過,這一次代理需要在動畫結束之后才能被銷毀(相比之下,在添加代理時,代理必須在動畫開始之前就被創建)。為了達到這一目的,我們使用`PropertyAction`元素,在動畫開始之前將`GridView.delayRemove`屬性設置為`true`,動畫完成之后,再將其設置為`false`。這保證了在代理被銷毀之前,動畫能夠順利完成。 ~~~ import QtQuick 2.0 Rectangle { width: 480 height: 300 gradient: Gradient { GradientStop { position: 0.0; color: "#dbddde" } GradientStop { position: 1.0; color: "#5fc9f8" } } ListModel { id: theModel ListElement { number: 0 } ListElement { number: 1 } ListElement { number: 2 } ListElement { number: 3 } ListElement { number: 4 } ListElement { number: 5 } ListElement { number: 6 } ListElement { number: 7 } ListElement { number: 8 } ListElement { number: 9 } } Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: 20 height: 40 color: "#53d769" border.color: Qt.lighter(color, 1.1) Text { anchors.centerIn: parent text: "Add item!" } MouseArea { anchors.fill: parent onClicked: { theModel.append({"number": ++parent.count}); } } property int count: 9 } GridView { anchors.fill: parent anchors.margins: 20 anchors.bottomMargin: 80 clip: true model: theModel cellWidth: 45 cellHeight: 45 delegate: numberDelegate } Component { id: numberDelegate Rectangle { id: wrapper width: 40 height: 40 gradient: Gradient { GradientStop { position: 0.0; color: "#f8306a" } GradientStop { position: 1.0; color: "#fb5b40" } } Text { anchors.centerIn: parent font.pixelSize: 10 text: number } MouseArea { anchors.fill: parent onClicked: { if (!wrapper.GridView.delayRemove) theModel.remove(index); } } GridView.onRemove: SequentialAnimation { PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: true } NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: Easing.InOutQuad } PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: false } } GridView.onAdd: SequentialAnimation { NumberAnimation { target: wrapper; property: "scale"; from: 0; to: 1; duration: 250; easing.type: Easing.InOutQuad } } } } } ~~~ 下圖是運行初始效果。 [![](https://box.kancloud.cn/2015-12-29_5682328a7fc93.png)](http://files.devbean.net/images/2015/08/delegate-animation.png) ## 改變代理的形狀 在表現列表時,常常會有這么一種機制:當數據項被選中時,該項會變大以充滿屏幕。這種行為可以將被激活的數據項放置在屏幕中央,或者為用戶顯示更詳細的信息。在下面的例子中,`ListView`的每一個數據項在點擊時都會充滿整個列表視圖,多出來的額外空間用于顯示更多信息。我們使用狀態實現這種機制。在這個過程中,列表的很多屬性都會發生改變。 首先,`wrapper`的高度會被設置為`ListView`的高度;縮略圖會變大,從先前的位置移動到一個更大的位置。除此以外,兩個隱藏的組件,`factsView`和`closeButton`會顯示在恰當的位置。最后,`ListView`的`contentsY`屬性會被重新設置為代理的`y`值。`contentsY`屬性其實就是視圖的可見部分的頂部距離。視圖的`interactive`屬性會被設置為`false`,這可以避免用戶通過拖動滾動條使視圖移動。當數據項第一次被點擊時,它會進入`expanded`狀態,是其代理充滿整個`ListView`,并且重新布局內容。當點擊關閉按鈕時,`expanded`狀態被清除,代理重新回到原始的狀態,`ListView`的交互也重新被允許。 ~~~ import QtQuick 2.0 Item { width: 300 height: 480 Rectangle { anchors.fill: parent gradient: Gradient { GradientStop { position: 0.0; color: "#4a4a4a" } GradientStop { position: 1.0; color: "#2b2b2b" } } } ListView { id: listView anchors.fill: parent delegate: detailsDelegate model: planets } ListModel { id: planets ListElement { name: "Mercury"; imageSource: "images/mercury.jpeg"; facts: "Mercury is the smallest planet in the Solar System. It is the closest planet to the sun. It makes one trip around the Sun once every 87.969 days." } ListElement { name: "Venus"; imageSource: "images/venus.jpeg"; facts: "Venus is the second planet from the Sun. It is a terrestrial planet because it has a solid, rocky surface. The other terrestrial planets are Mercury, Earth and Mars. Astronomers have known Venus for thousands of years." } ListElement { name: "Earth"; imageSource: "images/earth.jpeg"; facts: "The Earth is the third planet from the Sun. It is one of the four terrestrial planets in our Solar System. This means most of its mass is solid. The other three are Mercury, Venus and Mars. The Earth is also called the Blue Planet, 'Planet Earth', and 'Terra'." } ListElement { name: "Mars"; imageSource: "images/mars.jpeg"; facts: "Mars is the fourth planet from the Sun in the Solar System. Mars is dry, rocky and cold. It is home to the largest volcano in the Solar System. Mars is named after the mythological Roman god of war because it is a red planet, which signifies the colour of blood." } } Component { id: detailsDelegate Item { id: wrapper width: listView.width height: 30 Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top height: 30 color: "#333" border.color: Qt.lighter(color, 1.2) Text { anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter anchors.leftMargin: 4 font.pixelSize: parent.height-4 color: '#fff' text: name } } Rectangle { id: image width: 26 height: 26 anchors.right: parent.right anchors.top: parent.top anchors.rightMargin: 2 anchors.topMargin: 2 color: "black" Image { anchors.fill: parent fillMode: Image.PreserveAspectFit source: imageSource } } MouseArea { anchors.fill: parent onClicked: parent.state = "expanded" } Item { id: factsView anchors.top: image.bottom anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom opacity: 0 Rectangle { anchors.fill: parent gradient: Gradient { GradientStop { position: 0.0; color: "#fed958" } GradientStop { position: 1.0; color: "#fecc2f" } } border.color: '#000000' border.width: 2 Text { anchors.fill: parent anchors.margins: 5 clip: true wrapMode: Text.WordWrap color: '#1f1f21' font.pixelSize: 12 text: facts } } } Rectangle { id: closeButton anchors.right: parent.right anchors.top: parent.top anchors.rightMargin: 2 anchors.topMargin: 2 width: 26 height: 26 color: "#157efb" border.color: Qt.lighter(color, 1.1) opacity: 0 MouseArea { anchors.fill: parent onClicked: wrapper.state = "" } } states: [ State { name: "expanded" PropertyChanges { target: wrapper; height: listView.height } PropertyChanges { target: image; width: listView.width; height: listView.width; anchors.rightMargin: 0; anchors.topMargin: 30 } PropertyChanges { target: factsView; opacity: 1 } PropertyChanges { target: closeButton; opacity: 1 } PropertyChanges { target: wrapper.ListView.view; contentY: wrapper.y; interactive: false } } ] transitions: [ Transition { NumberAnimation { duration: 200; properties: "height,width,anchors.rightMargin,anchors.topMargin,opacity,contentY" } } ] } } } ~~~ 運行結果如下所示: [![](https://box.kancloud.cn/2015-12-29_5682328a91c8e.png)](http://files.devbean.net/images/2015/09/delegate-sharp.png) 點擊每一項可以開始一個動畫: [![](https://box.kancloud.cn/2015-12-29_5682328aa3e05.png)](http://files.devbean.net/images/2015/09/delegate-sharp-2.png) 這里展示的技術在某些方面非常實用,比如一些歌曲播放器允許用戶在點擊某首歌曲后,會將該歌曲的信息放大顯示等。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看