簡體   English   中英

Qml:包含 ListView 的 ScrollView 不會調整 ScrollBar 句柄

[英]Qml: ScrollView containing a ListView does not adjust ScrollBar handle

我正在嘗試根據需要將垂直滾動條添加到 ListView。 有人告訴我,最好的方法是將 ListView 放在 ScrollView 中,而不是將滾動條插入 ListView(就像在這個問題中),因為這樣可以提高 GPU 的效率。

我插入了它,如下例所示 - 但無論我嘗試什么,如果滾動條顯示,它的手柄總是占據整個高度,當然不會移動。

在此處輸入圖片說明

我希望你可以看看我的示例並給我一個建議,為什么滾動條沒有正確顯示。
代碼中有注釋解釋我做了什么以及為什么。

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4

Item
{
    readonly property int parentWidth: 280
    readonly property int parentMaxHeight: 400

    // Main reason for doing this - the items are custom objects and
    // their width does not automatically adjust for having the scroll bar or not
    // But also, to set scroll bars because Qt.ScrollBarAsNeeded makes them not show
    property bool scrollBarVisible: myListView.contentHeight > myListView.height

    width: parentWidth
    height: parentMaxHeight

    Rectangle
    {
        id: myMenuRect

        anchors.rightMargin: 2
        anchors.leftMargin: 2
        anchors.bottomMargin: 4
        anchors.topMargin: 4

        width: parentWidth
        height: myListView.height
        radius: 10
        z: 2

        color: "red"   // Adding this to show why the height of the rectangle must match the listview
    }

    ScrollView
    {
        id: myScrollView
        parent: myMenuRect
        anchors.fill: parent

        anchors.topMargin: 5
        anchors.bottomMargin: 5
        anchors.rightMargin: 5

        frameVisible: false

        // I have tried to set implicitHeight in many different ways,
        // no matter what I do the scroll bar handle occupies the enire bar and doesn't move

        // The Qt.ScrollBarAsNeeded didn't work... so I did this
        verticalScrollBarPolicy: scrollBarVisible ? Qt.ScrollBarAlwaysOn : Qt.ScrollBarAlwaysOff

    // Adding colors on scrollbar to show which part is showing     
    style: ScrollViewStyle
    {
        handle: Rectangle
        {
            implicitWidth: 10
            implicitHeight: 2
            radius: 10
            anchors.leftMargin: 1
            anchors.left: parent.left
            color: "yellow"
        }

        scrollBarBackground: Rectangle
        {
            implicitWidth: 12
            anchors.right: parent.right
            color: "green"
        }
    }

    ListView
    {
        id: myListView
        parent: myScrollView
        model: wifiComboListModel

        focus: true
        clip: true
        interactive: false

        width: parent.width

        // I am trying to tell my view to take the minimum space it needs that is below 
        // a certain height. Ignore the "myListView." prefixes here, I know they are not needed but 
        // make it easier to move this outside if needed
        height: (myListView.contentHeight > 0 ?
                     (myListView.contentHeight < parentMaxHeight ?
                          myListView.contentHeight : parentMaxHeight) : 0)

        // I made this as simple as possible, without affecting "quality"
        delegate: Text
        {
            text: _comboBoxText
            height: 70
            width: parent.width - 20
        }
    }

    ListModel
    {
        id: wifiComboListModel
    }

    // I want to populate my model from outside, not be static. Not sure if this affects the bars
    function populateComboBoxListModel()
    {
        wifiComboListModel.clear();
        for (var itemIndex = 0; itemIndex < listItems.length; itemIndex++)
        {
            wifiComboListModel.append
                ({
                    _id: itemIndex,
                    _comboBoxText: listItems[itemIndex]
                });
        }
    }

    Component.onCompleted:
    {
        populateComboBoxListModel();
    }

    property var listItems: [
            "This",
            "annoying",
            "list",
            "view",
            "does",
            "not behave the way",
            "I expect.",
            "I",
            "tried many",
            "things,",
            "now I am",
            "begging for your",
            "help",
            "."
    ]
}

您在 myMenuRect 中有一個高度綁定循環。 這是因為 myMenuRect 取決於列表視圖的高度,反之亦然。 修復后它似乎工作:

在此處輸入圖片說明

import QtQuick 2.0 
import QtQuick.Controls 1.4

ApplicationWindow
{
    readonly property int parentWidth: 280
    readonly property int parentMaxHeight: 400
    visible: true

    // Main reason for doing this - the items are custom objects and
    // their width does not automatically adjust for having the scroll bar or not
    // But also, to set scroll bars because Qt.ScrollBarAsNeeded makes them not show
    property bool scrollBarVisible: myListView.contentHeight > myListView.height

    width: parentWidth
    height: parentMaxHeight

    Rectangle
    {
        id: myMenuRect

        anchors.rightMargin: 2
        anchors.leftMargin: 2
        anchors.bottomMargin: 4
        anchors.topMargin: 4

        width: parentWidth
        height: parentMaxHeight
        radius: 10
        z: 2
    }

    ScrollView
    {
        id: myScrollView
        parent: myMenuRect
        anchors.fill: parent

        anchors.topMargin: 5
        anchors.bottomMargin: 5
        anchors.rightMargin: 5

        frameVisible: false

        // I have tried to set implicitHeight in many different ways,
        // no matter what I do the scroll bar handle occupies the enire bar and doesn't move

        // The Qt.ScrollBarAsNeeded didn't work... so I did this
        verticalScrollBarPolicy: scrollBarVisible ? Qt.ScrollBarAlwaysOn : Qt.ScrollBarAlwaysOff

        ListView
        {
            id: myListView
            model: wifiComboListModel

            focus: true
            clip: true
            interactive: false

            width: parent.width

            // I am trying to tell my view to take the minimum space it needs that is below
            // a certain height. Ignore the "myListView." prefixes here, I know they are not needed but
            // make it easier to move this outside if needed
            height: (myListView.contentHeight > 0 ?
                         (myListView.contentHeight < parentMaxHeight ?
                              myListView.contentHeight : parentMaxHeight) : 0)

            // I made this as simple as possible, without affecting "quality"
            delegate: Text
            {
                text: _comboBoxText
                height: 70
                width: parent.width - 20
            }
        }
    }

    ListModel
    {
        id: wifiComboListModel
    }

    // I want to populate my model from outside, not be static. Not sure if this affects the bars
    function populateComboBoxListModel()
    {
        wifiComboListModel.clear();
        for (var itemIndex = 0; itemIndex < listItems.length; itemIndex++)
        {
            wifiComboListModel.append
                ({
                    _id: itemIndex,
                    _comboBoxText: listItems[itemIndex]
                });
        }
    }

    Component.onCompleted:
    {
        populateComboBoxListModel();
    }

    property var listItems: [
            "This",
            "annoying",
            "list",
            "view",
            "does",
            "not behave the way",
            "I expect.",
            "I",
            "tried many",
            "things,",
            "now I am",
            "begging for your",
            "help",
            "."
    ]
}

我的 ScrollView 沒有表現的原因是為人父母:)

問題:即使我在 ListView 中設置了父級,似乎也不需要:

ListView
{
    parent: myScrollView

我必須做的事情實際上是將 ListView 嵌套在 ScrollView 中。

ScrollView
{
    id: myScrollView
    parent: myMenuRect
    anchors.fill: parent

    ListView
    {
        id: myListView
        model: wifiComboListModel

我認為“父”屬性可能不適用於所有控件,並且將來會記住這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM