How to implement pagination in a Qt 5.2 QML app

2019-05-22 12:07发布

I am trying to make an app which shows 3 pages at a time. The central page shows 3 rectangles displying sql query results 1-3 , the left page is a link to an image from query result 4, and the right page is also built from the same query and has a different layout. Now I am unable to fit these 3 pages into a listmodel and use pathview to make it look like a paginator, because all 3 pages are incongruent and not really a model, hence giving me error ListElement: cannot contain nested elements. I am pasting the code below. All i want is for the user to be able to flick between the pages, whether that involves a pathview or statechange with a decent transition to mimick flipping pages :

import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
import "content"


Rectangle{
    property ListModel mainModel
    id: tripleView
    visible: true
    width: 800
    height: 1400

    PathView {
        model: mainModel
        delegate: mainDelegate
        id: paginator
        preferredHighlightBegin: 0.5
        preferredHighlightEnd: 0.5

        anchors.fill: parent
        path: Path {

            startX: -tripleView.width * mainModel.count / 2 + tripleView.width / 2;
            startY: tripleView.height / 2
            PathLine {
                x: tripleView.width * mainModel.count /2 + tripleView.width / 2
                y: tripleView.height * .5 }
        }
    }

    Component {
        id: mainDelegate

        Rectangle {
        width: tripleView.width
        height: tripleView.height
        }
    }

    ListModel {
        id: regionsModel
        ListElement {

            name: "Stomach"
        }
        ListElement {
            name: "Lung"
        }
        ListElement {
            name: "Colorectal"
        }
        ListElement {
            name: "Pancreas"
        }
        ListElement {
            name: "Urinary Bladder"
        }

    }

    ListModel {
        id: mainModel
        ListElement{
            Rectangle{
                id: tnmPage
                width: parent.width
                height: container.height


                Rectangle {
                    id: menu
                    z: 2
                    width: parent.width  ;
                    height: 75



                    Component {

                        id: appDelegate
                        Rectangle {
                            width: genericText.width + 10; height: parent.height
                            id: wrapper
                            color: PathView.isCurrentItem ? "yellow" : "white"
                            Text {
                                id: genericText
                                height: parent.height
                                font.pointSize: 12
                                verticalAlignment: Text.AlignVCenter
                                //                anchors.topMargin: wrapper.top
                                color: wrapper.PathView.isCurrentItem ? "red" : "black"
                                text: name
                            }

                            MouseArea {
                                //  width:parent.width; height: parent.height
                                anchors.fill: parent
                                hoverEnabled: true
                                onClicked: {
                                    var List = mWindow.printi(name)
                                    t.content = List[1]
                                    node.content = List[2]
                                    mets.content = List[3]
                                    view.currentIndex = index


                                }

                            }
                        }
                    }



                    PathView {
                        id: view
                        width: 2500
                        height: parent.height
                        anchors.rightMargin: 18
                        anchors.bottomMargin: 0
                        anchors.leftMargin: -18
                        anchors.topMargin: 0
                        anchors.fill: parent
                        //        anchors.bottom: parent.bottom
                        //        anchors.top: parent.top
                        //        preferredHighlightBegin: .1
                        //        preferredHighlightEnd: .6

                        highlightRangeMode: PathView.StrictlyEnforceRange
                        //        anchors.rightMargin: 0
                        //        anchors.bottomMargin: 0
                        //        anchors.leftMargin: 2
                        //        anchors.topMargin: -71

                        z: 1
                        highlight: Component {
                            Rectangle {
                                color: "yellow"
                                visible: PathView.onPath

                            }
                        }

                        focus: true
                        model: regionsModel
                        delegate: appDelegate

                        path: Path {

                            startX: 0; startY: view.height *.5
                            PathLine { x: menu.width; y: view.height * .5 }
                        }


                    }
                }



                Flickable {
                    id: flick

                    anchors.topMargin: menu.bottom
                    width: parent. width
                    height: parent. height - menu.height
                    contentWidth: parent.width+200
                    contentHeight: container.height // this is calculated on amount of text
                    PinchArea {
                        width: Math.max(flick.contentWidth, flick.width)
                        height: Math.max(flick.height, flick.height)
                        pinch.minimumScale: 0.5
                        pinch.maximumScale: 3

                        property real initialWidth
                        property real initialHeight
                        x: 0
                        y: 0
                        //![0]
                        onPinchStarted: {
                            initialWidth = flick.contentWidth
                            initialHeight = flick.contentHeight
                            flick.interactive = false
                        }
                        onPinchUpdated: {
                            t.fontSize = t.size*pinch.scale
                            node.fontSize = node.size * pinch.scale
                            mets.fontSize = mets.size * pinch.scale

                        }

                        onPinchFinished: {
                            flick.returnToBounds()
                            flick.interactive = true
                        }



                        Rectangle {
                            id: container

                            MouseArea {
                                anchors.fill: parent
                                onDoubleClicked: {

                                    t.fontSize = 12
                                    node.fontSize = t.size
                                    mets.fontSize = t.size
                                }


                            }


                            anchors.top: flick.top
                            width: parent.width
                            height: t.height + node.height + mets.height

                            StageBox {
                                id: t
                                anchors.top: container.top
                                color: "#6acbd3"
                            }

                            StageBox {
                                id: node
                                anchors.top: t.bottom
                                color: "#1fd77b"
                            }
                            StageBox {
                                id: mets
                                anchors.top: node.bottom
                                color: "blue"
                            }
                        }
                    }


                }
            }

}

I realise the code above is lengthy, but i think it will give some idea about what i am trying to achieve. The examples i have found so far have simple pages displaying images and no nesting. Thank you for your help.

标签: pagination qml q
2条回答
成全新的幸福
2楼-- · 2019-05-22 12:14

I have managed a hack. Experimentally implemented in colored rectangles, this flickable behaves as a 3-page app starting at mid page and allowing flicking horizontally to access neighbouring pages. It works and I am sure with some tweaking it can suit similar applications as mine. Comments invited

import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0


Rectangle {
    state: "baseState"
    id: mainScreen
    width: 400
    height: 600


    Text {
        z:2
        id: logTxt
        height: 10
        width: 20
        function log(txt){
            text = txt+"\n"
        }
    }
    Flickable {
        boundsBehavior: StopAtBounds


        id: flick
        y: 48
        onContentXChanged: {
            if(flick.contentX>100 && mainScreen.state=="baseState" && flick.flickingHorizontally){
                logTxt.log(flick.contentX)
                mainScreen.state="State1"


            }


            if(flick.contentX<-100 && mainScreen.state=="baseState" && flick.flickingHorizontally){
                mainScreen.state="State2"
                logTxt.log(flick.contentX)

            }

            if(flick.contentX>100 && mainScreen.state=="State2" && flick.flickingHorizontally ){
                mainScreen.state="baseState"

                logTxt.log(flick.contentX)
                flick.contentX=0

            }


            if(flick.contentX<-100 && mainScreen.state=="State1" && flick.flickingHorizontally){
                logTxt.log(flick.contentX)
                mainScreen.state="baseState"


                flick.contentX=0

                logTxt.log(flick.contentX)
                Timer


            }

        }

        interactive: true
        width: 400
        height: 600
        transformOrigin: Item.Center
        flickableDirection: Flickable.HorizontalFlick

        Rectangle {
            width: 600

            height: 600
            id: container


            Rectangle {
                id:two
                visible: false
                x: 0
                z:3

                height: 600
                width: 400
                color: "grey"

            }
            Row{
                id: testGrid
                x:0
                visible: true


                y: 0
                z: 3

                width:600
                height: 600


                Rectangle {
                    id: a
                    anchors.top:parent.top

                    color:"#f6f7b1"
                    visible: true
                    z: 3
                    height: parent.height
                    width: 200
                }
                Rectangle {
                    id: b
                    anchors.top:parent.top

                    color:"#ffebeb"
                    visible: true
                    height: parent.height
                    width: 200
                }

                Rectangle {
                    id: c
                    y: -35
                    anchors.top:parent.top

                    color:"#b1d5f7"
                    height: parent.height
                    width: 200
                }

            }

            Rectangle {
                id: three
                visible: false
                z:2

                x:0
                height: parent.height
                width: 400
                color: "#028000"



            }



        }
    }
    states: [
        State {
            name: "State1"



            PropertyChanges {
                target: testGrid
                visible: false
            }

            PropertyChanges {
                target: two
                visible: true
            }

            PropertyChanges {
                target: three
                visible: false
            }
        },
        State {
            name: "State2"

            PropertyChanges {
                target: testGrid
                visible: false
            }

            PropertyChanges {
                target: three
                visible: true
            }
            PropertyChanges {
                target: two
                visible: false
            }

        },
        State {
            name: "baseState"


            PropertyChanges {

                target: testGrid
                visible: true
            }

            PropertyChanges {
                target: three
                visible: false
            }
            PropertyChanges {
                target: two
                visible: false
            }

        }
    ]
}
查看更多
Bombasti
3楼-- · 2019-05-22 12:18
登录 后发表回答