zhuzichu520 / FluentUI

FluentUI for QML
MIT License
3.12k stars 417 forks source link

如何使用 example 的首页卡片实现导航? #523

Closed BlandAlpha closed 1 month ago

BlandAlpha commented 1 month ago

本人是QT/QML新手,我按照 example 模仿搭建了带 navigationView 的页面,我想让最上面的 ListView 的大卡片实现 Page 的跳转。但是有点不太会用函数。请求帮助!

这是我的Home.qml文件:

    ListModel{
        id: model_header
        ListElement{
            icon: "qrc:/res/img/cinema.png"
            title: qsTr("Series")
            desc: qsTr("Check out different Bluey episodes and explore interesting stories of the Heelers.")
            url: "qrc:/page/Series.qml"
            clicked: function(model){
                navigationView.push(url)
            }
        }
        // 另外几个List Element
    }

这样会报错:ListElement: cannot use script for property value。但是加上 property var navigationView 就更不行了。

我看到下面的 最近添加 模块实现了我想要的方式,但是我用不太明白。我感觉是这个函数在起作用,但不会传参数:

MouseArea{
    id:item_mouse
    anchors.fill: parent
    hoverEnabled: true
    onClicked: {
        ItemsOriginal.startPageByItem(modelData)
    }
}

ItemsOriginal.qml:

function startPageByItem(data){
    navigationView.startPageByItem(data)
}
BlandAlpha commented 1 month ago

好吧,虽然没人回答但是我摸索出方法了。

仔细看了下源码,发现在 FluNavigationView.qml 文件里面包含了好几个函数,这里面就有 startPageByItem() 以及 push() 两种页面跳转方式的实现方法。接下来我讲讲我的理解,不一定对,但我搞定了。


tl;dr

ItemsOriginal.qml 文件中创建一个传递用函数:

    function setCurrentIndex(index){
        navigationView.setCurrentIndex(index)
    }

再在卡片中使用 setCurrentIndex() 函数,传递需要的 index 参数:

        ListElement{
            // 其他参数
            index: 1
            clicked: function(model){
                ItemsOriginal.setCurrentIndex(model.index)
            }
        }

发现过程

我之前尝试过,发现 push() 可以正常跳转,但左边的按钮会处于不被按下的状态。 startPageByItem() 对于example是有用的,但他的参数是一个 model,我只有url。

所以我点进源码大概看了下,发现其中真正起作用的函数是 setCurrentIndex(i)。以下是函数本体:

    function setCurrentIndex(index){
        var item = nav_list.model[index]
        if(item.url){
            nav_list.currentIndex = index
            if(item instanceof FluPaneItem){
                item.tap()
            }
        }else{
            item.onTapListener()
        }
    }

我的理解

我感觉 item.tap() 就是让左边成功按下去的魔法函数。因此我可以直接使用这个函数并传一个 index 进去就行。经过尝试,发现他的编号是从上往下以此增加的,如图:

界面截图

所以只需要对每个卡片设置一个 index 变量,让他分别等于其对应的值,再传递给 setCurrentIndex 就行了。