QML Pathview 如何滑动图标

问题描述 投票:0回答:1

我有以下需求,找不到正确的入口

应显示图标列表中最多 5 个图标。

开始时,列表中的第一个图标应该在容器的中间。 单击左箭头按钮,下一个图标位于中间,第一个图标向左移动。

在列表的末尾,最后一个图标保留在中间。中心左右两侧的图标应小于中心的图标。

开始:

中:

结束:

路径视图到目前为止有效,图标来自 c++ 类并通过委托显示。

我有一个例子中的路径块,但它不能直接适合这个,我还不明白这里到底定义了什么。

我是否需要 5 个 PathAttribute 块和 4 个 PathLine?我如何从中间的第一个图标开始?如何根据图标的位置更改图标的大小以及如何使它们靠得更近

如果有任何帮助开始,我会很高兴

Coverflow.qml

Rectangle {
    id: root
    height: 200
    width: 400      
    Layout.preferredHeight: height 
    Layout.preferredWidth: width
    color: "white"
    
    PathView {
        id: view
        anchors.fill: parent
        pathItemCount: 5
        
        model: m_screen.coverflowModel
        delegate: CoverflowDelegate { height: view.height; width: view.height; p_icon: icon; p_z: PathView.iconOrder }
        
        path: Path {
            startX: 0; startY: view.height/2
            PathAttribute { name: "iconScale"; value: 0.6 }
            PathAttribute { name: "iconOpacity"; value: 0.9 }
            PathAttribute { name: "angle"; value: 90}
            PathLine {x: view.width / 2; y: view.height/2 }
            PathAttribute { name: "iconScale"; value: 1 }
            PathAttribute { name: "iconOpacity"; value: 1 }
            PathAttribute { name: "angle"; value: 0 }
            PathLine {x: view.width; y: view.height/2 }
            PathAttribute { name: "itemScale"; value: 0.6  }
            PathAttribute { name: "itemOpacity"; value: 0.9 }
            PathAttribute { name: "angle"; value: -90 }
        }
    }
 }

CoverflowDelegate.qml

Item {
    id: delegate
    property string p_icon
    property string p_source: (!p_icon || p_icon.length === 0)  ? "" : "image://iconprovider/" + p_icon
    property int p_z
    Rectangle {
        color: "lightgrey"
        width: 70; height: 70
        radius: 10
        z: p_z
        Image {
            anchors.centerIn: parent
            source: p_source
            sourceSize.width: parent.width * 0.8
        }
    }
}
path qml
1个回答
2
投票

[编辑/重写以使用 highlightRangeMode]

你可以用

ListView
+
Button
模拟这个。我们可以配置
ListView

    height: 120
    width: 600 // i.e. height * 5
    orientation: ListView.Horizontal
    highlightRangeMode: ListView.StrictlyEnforceRange
    preferredHighlightBegin: width / 2
    preferredHighlightEnd: width / 2

ListView
将负责水平滚动和对齐项目以创建干净的动画和用户体验。

highlightRangeMode
preferredHighlightBegin
preferredHighlightEnd
属性确保突出显示的项目始终位于
ListView
的中心。

import QtQuick
import QtQuick.Controls
Page {
    ListView {
        anchors.centerIn: parent
        width: height * 5
        height: 120
        clip: true
        model: MyListModel { id: listModel }
        orientation: ListView.Horizontal
        highlightRangeMode: ListView.StrictlyEnforceRange
        preferredHighlightBegin: width / 2
        preferredHighlightEnd: width / 2
        delegate: MyDelegate { }
    }
}

// MyDelegate.qml
import QtQuick
import QtQuick.Controls
Item {
    property ListView listView: ListView.view
    property bool isCurrentItem: ListView.isCurrentItem
    property int dist: Math.abs(listView.width / 2 + listView.contentX - (x + width / 2))
    width: height
    height: listView.height
    Button {
        anchors.centerIn: parent
        //visible: !dummy
        width: parent.height / (1 + dist * 0.002)
        height: width
        background: Rectangle {
            radius: 10
            border.color: "#888"
            color: isCurrentItem ? "#ccc" : "#eee"
        }
        icon.source: ico
        icon.width: parent.width * .6
        icon.height: parent.height * .6
        icon.color: isCurrentItem ? "black" : "#888"
        Label {
            anchors.horizontalCenter: parent.horizontalCenter
            y: parent.height * 3 / 4
            text: nam
            visible: !dummy
            color: "#08f"
            z: 2
        }
    }
}

// MyListModel.qml
import QtQuick
import QtQuick.Controls
ListModel {
    Component.onCompleted: {
        append( { nam: "One", ico: "target.svg", val: 1 } );
        append( { nam: "Two", ico: "pencil.svg", val: 2 } );
        append( { nam: "Three", ico: "monitor.svg", val: 3 } );
        append( { nam: "Four", ico: "target.svg", val: 4 } );
        append( { nam: "Five", ico: "pencil.svg", val: 5 } );
        append( { nam: "Six", ico: "monitor.svg", val: 6 } );
        append( { nam: "Seven", ico: "target.svg", val: 7 } );
        append( { nam: "Eight", ico: "pencil.svg", val: 8 } );
    }
}

// target.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<circle cx="16" cy="16" r="8" stroke="black" stroke-width="1" fill="none" />
<path stroke="black" stroke-width="0.5" fill="black" d="M 16 12 L 15 11 L 15 6 L 17 6 L 17 11 z" />
<path stroke="black" stroke-width="0.5" fill="black" d="M 20 16 L 21 15 L 26 15 L 26 17 L 21 17 z"/>
<path stroke="black" stroke-width="0.5" fill="black" d="M 16 20 L 17 21 L 17 26 L 15 26 L 15 21 z "/>
<path stroke="black" stroke-width="0.5" fill="black" d="M 12 16 L 11 17 L 6 17 L 6 15 L 11 15 z"/>
</svg>

// monitor.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect stroke="black" fill="none" x="5" y="7" width="22" height="14" rx="1"/>
<path stroke="black" stroke-width="0.1" fill="black" d="M 2 23 L 30 23 L 30 24 L 29 25 L 3 25 L 2 24 z L 14 23.5 L 14 24.5 L 18 24.5 L 18 23.5 L 14 23.5"/>
<path stroke="black" stroke-width="0.1" fill="black" d="M 22 13 L 23 13 L 23 15 L 10 15 L 10 15.8 L 8 14.5 L 10 13.2 L 10 14 L 22 14 z
"/>
</svg>

// pencil.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<path stroke="black" stroke-width="1" fill="transparent" d="M 24 18 L 24 25
A 1 1 0 0 1 23 26 L 5 26 A 1 1 0 0 1 4 25 L 4 7 A 1 1 0 0 1 5 6 L 23 6 A 1 1 0 0 1 24 7 L 24 10"/>
<path stroke="black" stroke-width="0.5" fill="black" d="M 27 13 L 25 11 L 26 10 A 1 1 0 0 1 27 10 L 28 11 A 1 1 0 0 1 28 12 z
"/>
<path stroke="black" stroke-width="0.5" fill="black" d="M 26 14 L 21 19 L 19 17 L 24 12 z"/>
<path stroke="black" stroke-width="0.5" fill="transparent" d="M 21 19 L 20 20 L 18 20 L 18 18 L 19 17" />
<rect x="18" y="19" width="1" height="1" fill="black"/>
</svg>

您可以在线试用!

© www.soinside.com 2019 - 2024. All rights reserved.