Qml: ScrollView, содержащий ListView, не регулирует дескриптор ScrollBar - PullRequest
0 голосов
/ 06 февраля 2020

Я пытаюсь при необходимости добавить вертикальную полосу прокрутки в ListView. Мне сказали, что лучший подход - поместить ListView внутри ScrollView, а не вставлять полосу прокрутки в ListView (как в этот вопрос ), потому что это сделает его более эффективным для графического процессора.

Я вставил его, как в примере ниже - но независимо от того, что я пытался, если полоса прокрутки показывает, ее ручка всегда принимает всю высоту и, конечно, не двигается.

enter image description here

Я надеюсь, что вы можете взглянуть на мой образец и дать мне предложение, почему полоса прокрутки не отображается должным образом.
В коде есть комментарии, объясняющие что я сделал и почему.

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",
            "."
    ]
}

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

у вас есть привязка l oop для высоты в myMenuRect. Это происходит потому, что myMenuRect зависит от высоты представления списка и наоборот. После исправления вроде работает:

enter image description here

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",
            "."
    ]
}
0 голосов
/ 07 февраля 2020

Причиной, по которой мой ScrollView не вел себя, было родительство:)

Проблема: несмотря на то, что я установил родителя в ListView, кажется, что это не заняло:

ListView
{
    parent: myScrollView

То, что я должен был сделать, чтобы это работало, на самом деле было вложением ListView внутри ScrollView.

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

    ListView
    {
        id: myListView
        model: wifiComboListModel

Я думаю, что свойство "parent" может работать не для всех элементов управления, и запомнит это в будущем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...