【问题标题】:Hide first or last item in PathView隐藏 PathView 中的第一个或最后一个项目
【发布时间】:2021-12-18 01:56:44
【问题描述】:

我在 QML 中编写了一个简单的轮播。我在 Ubuntu 20.04 下运行 Qt 6.2.0。

import QtQuick

PathView {
    id: view

    property int item_width: 864
    property int item_gap: 250

    anchors.fill: parent
    anchors.bottomMargin: 150
    anchors.topMargin: 50
    pathItemCount: 3
    preferredHighlightBegin: 0.5
    preferredHighlightEnd: 0.5
    highlightRangeMode: PathView.StrictlyEnforceRange
    highlightMoveDuration: 1000
    snapMode: PathView.SnapToItem
    rotation: -90

    model: modelContent
    delegate: DelegateContent { }

    path: Path {
        startX: -item_gap; startY: view.height / 2
        PathAttribute { name: "iconScale"; value: 0.7 }
        PathAttribute { name: "iconOpacity"; value: 0.1 }
        PathAttribute { name: "iconOrder"; value: 0 }
        PathLine {x: view.width / 2; y: view.height / 2; }
        PathAttribute { name: "iconScale"; value: 1 }
        PathAttribute { name: "iconOpacity"; value: 1 }
        PathAttribute { name: "iconOrder"; value: 9 }
        PathLine {x: view.width + item_gap; y: view.height / 2; }
    }

    Component.onCompleted: {
        gesture.gestureFired.connect(gestureFired)
    }

    onCurrentIndexChanged: {
        itemAtIndex(0).visible = currentIndex < (count - 1)
    }

    function gestureFired(type) {
        switch (type) {
        case 1:
            if (view.currentIndex > 0) view.decrementCurrentIndex();
            break;

        case 2:
            if (view.currentIndex < view.count - 1) view.incrementCurrentIndex();
            break;
        }
    }
}

效果很好。当前索引的更改仅以编程方式完成(来自 C++ 的gestureFired 信号)。如您所见,没有循环行为。

因此,我想隐藏第一项(选择最后一项时)或最后一项(选择第一项时)。

我试过上面的代码:

onCurrentIndexChanged: {
    itemAtIndex(0).visible = currentIndex < (count - 1)
}

想法是:如果currentIndex 是最后一个元素(=count - 1),则第一项的visible 属性应该为false。

但它不起作用:

TypeError:值为空,无法转换为对象

它指的是哪个“价值”? 我调试了currentIndexcount,它们都是有效的(4 和5)。

实现这种行为的正确方法是什么?

【问题讨论】:

  • 我不同意将标签从qt5更改为qt6qt5 有 1.6k 的观察者,qt6 只有 31 个!而且差别也不是很大……
  • Qt6 在下面做了很大的改变,所以它不是 Qt 5.16 而是 Qt 6。所以最好使用那个标签。如果您想引用观察者,请查看具有 21.7k 的相关 Qt 标签。其他标签通常指定环境。另一方面,如果您查看 SO 中 Qt 社区的活动,您会发现我们很少(可能少于 50 个)。

标签: qt qml carousel qt6


【解决方案1】:

一个简单的解决方案是在委托中进行绑定:

import QtQuick

Column {
    id: root

    required property int index

    // mapping model roles
    required property string name

    visible: _internals.calculateVisibility()

    QtObject {
        id: _internals

        function calculateVisibility() {
            console.log(index, root.PathView.isCurrentItem, root.PathView.view.currentIndex)
            if ((root.index === (root.PathView.view.count - 1)) && (root.PathView.view.currentIndex === 0))
                return false;
            else if ((root.index === 0) && (root.PathView.view.currentIndex === (root.PathView.view.count - 1)))
                return false;
            return true;
        }

    }

    Text {
        id: nameText

        text: root.name
        font.pointSize: 16
        color: root.PathView.isCurrentItem ? "red" : "blue"
    }

}

【讨论】:

  • 出于好奇,将function 嵌入QtObject 的目的是什么?即使没有,我也可以声明它,它似乎也能正常工作。
  • 您的解决方案几乎奏效了!唯一需要注意的是,当当前索引更改(项目移动)时,以前隐藏的委托现在可见!而且不好看。
  • @Mark 这个想法是隐藏不应该公开的功能。这也是同样的原因,因为在 C++ 中有公共的、受保护的和私有的。
  • 作为丑陋的解决方法,我添加了一个Timer,它延迟了root.visibilityfalsetrue 的相同数量的view.highlightMoveDuration 的切换
猜你喜欢
  • 2021-10-02
  • 1970-01-01
  • 2017-05-06
  • 2015-07-22
  • 1970-01-01
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多