【问题标题】:Scroll two or more List views in QML在 QML 中滚动两个或多个列表视图
【发布时间】:2017-08-29 14:03:29
【问题描述】:

我需要使用单个滚动条一次滚动两个或多个列表视图。最初,我在Flickable 中使用了Column,但滚动没有按预期发生。后来,我使用了ListView,即使这样也不能正确滚动。

那么如何使用滚动条滚动列表视图/布局内容项?我应该使用ScrollViewFlickable 还是其他?

【问题讨论】:

  • Column + Flickable 没有按预期滚动?
  • 考虑三列,其中 col1 有 10 项,col2 有 15 项,col3 有 20 项。现在我应该找到一个包含最多项目的列,并且应该将Flickable contentHeight 设置为相同然后它可以工作! .就我而言,我应该每次都这样做,因为所有项目都动态插入到列中。

标签: qt listview qml qtquick2 flickable


【解决方案1】:

库存滚动条只会挂接到单个可滚动项。但是,制作自定义滚动条并将多个视图挂接到它是微不足道的:

  Row {
    Flickable {
      width: 50
      height: main.height
      contentHeight: contentItem.childrenRect.height
      interactive: false
      contentY: (contentHeight - height) * scroller.position
      Column {
        spacing: 5
        Repeater {
          model: 20
          delegate: Rectangle {
            width: 50
            height: 50
            color: "red"
            Text {
              anchors.centerIn: parent
              text: index
            }
          }
        }
      }
    }
    Flickable {
      width: 50
      height: main.height
      contentHeight: contentItem.childrenRect.height
      interactive: false
      contentY: (contentHeight - height) * scroller.position
      Column {
        spacing: 5
        Repeater {
          model: 30
          delegate: Rectangle {
            width: 50
            height: 50
            color: "cyan"
            Text {
              anchors.centerIn: parent
              text: index
            }
          }
        }
      }
    }
    Rectangle {
      id: scroller
      width: 50
      height: 50
      color: "grey"
      property real position: y / (main.height - 50)
      MouseArea {
        anchors.fill: parent
        drag.target: parent
        drag.minimumY: 0
        drag.maximumY: main.height - 50
        drag.axis: Drag.YAxis
      }
    }
  }

请注意,即使视图具有不同的内容高度,它也可以正常工作,相对于滚动条位置滚动每个视图:

意识到这个问题没有说得那么好,以防万一有人想同时滚动多个视图,我仍然会分享另一种有趣的方法,类似于缓动盘,可以无限期地向各个方向移动而不是像滚动条那样具有有限的范围。此解决方案将同步滚动两个视图,直到它们达到其范围的范围。与 GrecKo 的回答不同,当视图大小不同时,这永远不会给您留下“空视图”:

  Row {
    Flickable {
      id: f1
      width: 50
      height: main.height
      contentHeight: contentItem.childrenRect.height
      interactive: false
      Connections {
        target: jogger
        onScroll: f1.contentY = Math.max(0, Math.min(f1.contentHeight - f1.height, f1.contentY + p))
      }
      Column {
        spacing: 5
        Repeater {
          model: 20
          delegate: Rectangle {
            width: 50
            height: 50
            color: "red"
            Text {
              anchors.centerIn: parent
              text: index
            }
          }
        }
      }
    }
    Flickable {
      id: f2
      width: 50
      height: main.height
      contentHeight: contentItem.childrenRect.height
      interactive: false
      Connections {
        target: jogger
        onScroll: f2.contentY = Math.max(0, Math.min(f2.contentHeight - f2.height, f2.contentY + p))
      }
      Column {
        spacing: 5
        Repeater {
          model: 30
          delegate: Rectangle {
            width: 50
            height: 50
            color: "cyan"
            Text {
              anchors.centerIn: parent
              text: index
            }
          }
        }
      }
    }
    MouseArea {
      id: jogger
      width: 50
      height: main.height
      drag.target: knob
      drag.minimumY: 0
      drag.maximumY: main.height - 50
      drag.axis: Drag.YAxis
      signal scroll(real p)
      property real dy: 0
      onPressed: dy = mouseY
      onPositionChanged: {
        scroll(dy - mouseY)
        dy = mouseY
      }
      onScroll: console.log(p)
      Rectangle {
        anchors.fill: parent
        color: "lightgrey"
      }
      Rectangle {
        id: knob
        visible: parent.pressed
        width: 50
        height: 50
        color: "grey"
        y: Math.max(0, Math.min(parent.mouseY - 25, parent.height - height))
      }
    }
  }

“慢跑”方法的另一个优点是它不是相对的,而是绝对的。这意味着如果您的视图很大,如果您使用滚动条,即使是单个像素也可能导致内容发生很大变化,而在绝对模式下运行的慢跑将始终滚动相同数量的像素,而不管内容大小,即在需要精度的地方很方便。

【讨论】:

  • 看着很烦 :)
  • @GrecKo - 因为他们抵消了?如果内容高度不同,但您希望均匀滚动多个视图的整个内容,这是不可避免的。
  • 确实在这种情况下这是不可避免的,但我不确定 OP 是否想要统一滚动。无论如何,我已经做出了另一个没有统一滚动的替代答案。
  • 嗯,这是有道理的,因为滚动条是一个相对滚动元素。现在,如果它更像是一个缓动轮,向上或向下拉,那么视图只会尽可能远,而不会像您的解决方案那样留下空白。
  • 有点离题,但如果你想“绝对”滚动鼠标上的滚轮并在触摸屏上轻弹/拖动;)我不觉得留空是一个问题,但它可能是在某些情况下。
【解决方案2】:

您可以将Flickable 与您的Columns 一起使用。 我不知道你的 Columns 是如何水平布局的,但如果它们在 Row 内,那就很简单了:

import QtQuick 2.7
import QtQuick.Controls 2.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Multi Column")

    Flickable {
        anchors.fill: parent
        contentWidth: row.implicitWidth
        contentHeight: row.implicitHeight
        Row {
            id: row
            Column {
                spacing: 5
                Repeater {
                    model: 20
                    delegate: Rectangle {
                        width: 50
                        height: 50
                        color: "red"
                        Text {
                            anchors.centerIn: parent
                            text: index
                        }
                    }
                }
            }
            Column {
                spacing: 5
                Repeater {
                    model: 30
                    delegate: Rectangle {
                        width: 50
                        height: 50
                        color: "cyan"
                        Text {
                            anchors.centerIn: parent
                            text: index
                        }
                    }
                }
            }
        }
        ScrollBar.vertical: ScrollBar { }
    }
}

即使他们不在Row 中,您也可以这样做:
contentHeight: Math.max(column1.height, column2.height, ...)

演示:

【讨论】:

  • 不确定这个分类如何滚动两个或更多视图。但也许 OP 的措辞不恰当,无法说明预期的结果。也许所有 OP 需要的只是一种适当调整内容高度以动态更改列的方法。
  • 鉴于 OP 对我对该问题的评论的回答,我想说这就是 OP 的全部需求。
  • 感谢您的解决方案..这就是我所需要的。不要介意“OP”是什么意思??
  • @pra7 - 它表示原始帖子或原始海报,即它指的是问题或发起问题的人,这是由上下文暗示的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-21
  • 1970-01-01
相关资源
最近更新 更多