QML 中的 Flickable / ScrollView 带有始终可见的滚动条,在右下角不重叠

Posted

技术标签:

【中文标题】QML 中的 Flickable / ScrollView 带有始终可见的滚动条,在右下角不重叠【英文标题】:Flickable / ScrollView in QML with always-visible scrollbars that don't overlap in the bottom right corner 【发布时间】:2021-09-01 00:52:56 【问题描述】:

我正在尝试实现一个类似于默认 ScrollView 小部件的小部件,除了滚动条始终可见并且更厚且更易于查看。似乎没有一种简单的方法来实际主题化或调整 ScrollView 上滚动条的样式以获得我想要的,所以我最终试图破解 Flickable 来做到这一点。

但是,像这样覆盖Flickable 中的滚动条有一个缺点:结果要么使滚动条在右下角重叠,要么垂直的滚动条一直向下延伸,而水平的滚动条适合剩余空间。应该发生的是,在角落里应该留下一个小方块,滚动条都不应该去。

使用anchors.bottom / anchors.right 行,我可以让那个角落按预期运行。但代价是滚动条的顶部/左侧现在看不见了。

我可以通过将顶部/左侧锚点(即注释行)分配给相应的flickable 边界来“解决”这个滚动条开始的问题。然而,虽然它看起来不错,但它会导致QML ScrollBar: Possible anchor loop detected on vertical anchor. 警告流淹没控制台。有什么方法可以避免这个锚循环错误,还是我应该忽略/过滤这些警告?


代码(“ScrollPane.qml”):

/// ScrollPane - Custom ScrollView-like widget based on Flickable,
/// with additional functionality for getting the theming we want.
import QtQuick 2.3
import QtQuick.Controls 2.3

// The region that displays the contents
Flickable 
    id: flickable
    clip: true
    
    boundsBehavior: Flickable.StopAtBounds
    //boundsMovement: Flickable.StopAtBounds
    
    // Increase scrolling speed, as Flickable is too sluggish
    // Note: Windows default is 2500
    
    //maximumFlickVelocity : 10000  // XXX: overshoots
    maximumFlickVelocity : 7000
    
    // Component.onCompleted: 
    //  console.log("scroll view rate = %1".arg(maximumFlickVelocity))
    // 
    
    // Scrollbars ===========================
    
    // Scrollbar Parameters -----------------
    
    // Width/Thickness of Gutter (px)
    property int gutterSize : 18
    
    // Width/Thickness of Scroll Thumb (px)
    property int thumbSize : gutterSize - 3
    
    
    // Gutter Color
    property color gutterColor: "#FFFFFF"
    property color gutterBorderColor: Qt.rgba(0, 0, 0, 0.9)
    
    // Scroll Thumb Colors
    property color thumbColor: "#BBBBBB"
    property color thumbPressedColor: "#777777"
    property color thumbBorderColor: "#CCCCCC"
    
    // Vertical Scrollbar: Always On --------
    ScrollBar.vertical: ScrollBar 
        id: verticalScrollbar
        
        policy: ScrollBar.AlwaysOn
        
        /// NOTE: This is needed to keep the bottom-right corner empty. But, is buggy due to the Anchor Loop warning
        //anchors.top: flickable.top  // FIXME: Enable to show rounded top; Disabled due to Anchor Loop warning
        anchors.bottom: horizontalScrollbar.top
        
        // Gutter/Trough
        background: Rectangle 
            implicitWidth: flickable.gutterSize
            border 
                color: flickable.gutterBorderColor
                width: 1.5
            
            color: flickable.gutterColor
            opacity: 0.2
        
        
        // Scroll Thumb
        contentItem: Rectangle 
            implicitWidth: flickable.thumbSize
            radius: width / 2
            border 
                color: flickable.thumbBorderColor
                width: 1
            
            color: parent.pressed ? flickable.thumbPressedColor
                                  : flickable.thumbColor
            opacity: 0.9
        
    
    
    // Horizontal Scrollbar: As Needed --------
    ScrollBar.horizontal: ScrollBar 
        id: horizontalScrollbar
        
        policy: ScrollBar.AsNeeded
        

        /// NOTE: This is needed to keep the bottom-right corner empty. But, is buggy due to the Anchor Loop warning
        //anchors.left: flickable.left // FIXME: Enable to show rounded LHS; Disabled due to Anchor Loop warning
        anchors.right: verticalScrollbar.left
        
        // Gutter/Trough
        background: Rectangle 
            implicitHeight: flickable.gutterSize
            border 
                color: flickable.gutterBorderColor
                width: 1.5
            
            color: flickable.gutterColor
            opacity: 0.2
        
        
        // Scroll Thumb
        contentItem: Rectangle 
            implicitHeight: flickable.thumbSize
            radius: height / 2
            border 
                color: flickable.thumbBorderColor
                width: 1
            
            color: parent.pressed ? flickable.thumbPressedColor
                                  : flickable.thumbColor
            opacity: 0.9
        
    


【问题讨论】:

【参考方案1】:

好吧,您可以在选择另一个父级时禁用滚动条的自动调整大小:

    ScrollBar.vertical: ScrollBar 
        id: verticalScrollbar

        policy: ScrollBar.AlwaysOn

        parent: flickable.parent

        anchors.top: flickable.top
        anchors.right: flickable.right
        anchors.bottom: flickable.bottom
        anchors.bottomMargin: 20
    

    ScrollBar.horizontal: ScrollBar 
        id: horizontalScrollbar

        policy: ScrollBar.AsNeeded

        parent: flickable.parent
        anchors.left: flickable.left
        anchors.right: flickable.right
        anchors.bottom: flickable.bottom
        anchors.rightMargin: 20
    

这是否满足您的需求?

【讨论】:

以上是关于QML 中的 Flickable / ScrollView 带有始终可见的滚动条,在右下角不重叠的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QML 中处理来自父 Flickable 的 gridview contentY 和 Y 位置

Qt Quick QML Flickable 禁用轻弹并仅启用滚动

QML FlipableFlickable和状态与动画 下篇

QML FlickArea 中心内容

QML FlipableFlickable和状态与动画 上篇

如何将 QML ScrollView 滚动到中心?