QML之ScrollView(滚动视图)

ScrollView 是 Qt Quick Controls 2 中提供的可滚动视图容器,用于创建可滚动区域。以下是详细使用方法:

基本用法

qml

import QtQuick 2.15
import QtQuick.Controls 2.15

ScrollView {
    id: scrollView
    width: 300
    height: 200
    clip: true

    // 背景设置(Qt 5.15+)
    background: Rectangle {
        color: "#f0f0f0"
        border.color: "#cccccc"
    }

    // 滚动条样式定制
    ScrollBar.vertical: ScrollBar {
        policy: ScrollBar.AsNeeded
        width: 10
        background: Rectangle { color: "#e0e0e0" }
        handle: Rectangle {
            color: "#a0a0a0"
            radius: 4
            implicitWidth: 10
        }
    }

    // 内容项(必须设置宽度!)
    Column {
        width: scrollView.viewport.width  // 关键绑定
        spacing: 10

        Repeater {
            model: 50
            Rectangle {
                width: parent.width
                height: 40
                color: index % 2 ? "#ffffff" : "#f8f8f8"
                Text { text: "Item " + index; anchors.centerIn: parent }
            }
        }
    }

    // 监听滚动事件
    ScrollBar.vertical.onPositionChanged: {
        console.log("Scroll position:", ScrollBar.vertical.position)
    }
}

属性

核心属性

属性 类型 默认值 说明
contentWidth real 0 内容区域的宽度(需显式设置或通过内容自动计算)
contentHeight real 0 内容区域的高度
viewport Item 只读 视口项(用于绑定内容宽度:width: ScrollView.viewport.width
clip bool false 是否裁剪超出部分(建议设为 true 提升性能)

滚动条控制属性

垂直滚动条(ScrollBar.vertical
属性 类型 默认值 说明
policy enum ScrollBar.AsNeeded 显示策略:AsNeeded/AlwaysOn/AlwaysOff
position real 0.0 当前滚动位置(0.0-1.0)
size real 0.0 滚动条大小比例(0.0-1.0)
interactive bool true 是否允许用户拖动滚动条
水平滚动条(ScrollBar.horizontal

(属性同垂直滚动条)

样式属性

属性 类型 说明
background Component 背景组件(Qt 5.15+)
ScrollBar.horizontal.background Component 水平滚动条背景
ScrollBar.vertical.background Component 垂直滚动条背景
ScrollBar.horizontal.handle Component 水平滚动条滑块
ScrollBar.vertical.handle Component 垂直滚动条滑块

行为属性

属性 类型 默认值 说明
flickable Flickable 只读 内部 Flickable 对象(高级控制)
wheelEnabled bool true 是否启用鼠标滚轮滚动
scrollSpeed real 50 滚轮滚动速度(像素/步)

信号

信号 说明
contentWidthChanged 内容宽度变化时触发
contentHeightChanged 内容高度变化时触发
ScrollBar.vertical.positionChanged 垂直滚动位置变化时触发
ScrollBar.horizontal.positionChanged 水平滚动位置变化时触发

滚动条自定义

qml

ScrollView {
    // 自定义滚动条样式
    ScrollBar.horizontal: ScrollBar {
        policy: ScrollBar.AlwaysOn
        height: 10
        background: Rectangle { color: "lightgray" }
    }
    
    ScrollBar.vertical: ScrollBar {
        policy: ScrollBar.AsNeeded
        width: 10
        background: Rectangle { color: "lightgray" }
    }
}

嵌套内容布局

qml

ScrollView {
    anchors.fill: parent
    
    Column {
        spacing: 10
        width: parent.width
        
        Repeater {
            model: 50
            Rectangle {
                width: parent.width
                height: 40
                color: index % 2 ? "lightblue" : "lightgreen"
                Text { text: "项目 " + index; anchors.centerIn: parent }
            }
        }
    }
}

与 Flickable 的区别

  1. ScrollView 优势

    • 自动处理滚动条

    • 更简单的 API

    • 内置触摸屏优化

  2. Flickable 优势

    • 更精细的控制

    • 支持边界反弹效果

    • 适合自定义滚动行为

常见问题解决方案

  1. 内容不滚动

    qml

    // 错误:内容宽度未绑定
    Label {
        width: implicitWidth  // 错误写法
    }
    
    // 正确:
    Label {
        width: ScrollView.viewport.width  // 正确写法
    }

  2. 动态更新内容

    qml

    ScrollView {
        id: scrollView
        // ...
    }
    
    Button {
        text: "滚动到底部"
        onClicked: scrollView.ScrollBar.vertical.position = 1.0
    }
  3. 性能优化

    qml

    ScrollView {
        clip: true  // 启用裁剪提高性能
        // ...
    }

高级用法

  1. 自定义滚动速度

    qml

    ScrollView {
        ScrollBar.vertical: ScrollBar {
            stepSize: 0.1  // 调整滚动步长
        }
    }
  2. 监听滚动位置

    qml

    ScrollView {
        ScrollBar.vertical.onPositionChanged: {
            console.log("当前位置:", ScrollBar.vertical.position)
        }
    }
  3. 与 ListView 结合

    qml

    ScrollView {
        ListView {
            model: 100
            delegate: ItemDelegate { text: "项目 " + index }
            width: parent.width
        }
    }