当前位置: 首页 > news >正文

QML指示控件:PageIndicator

目录

引言

1. PageIndicator特性

2. 基础实现:与SwipeView联动

2.1 基本示例

2. 交互增强版

3. 属性介绍

4. 实践方案

4.1 动态页面管理(分页加载)

4.2 形状定制:菱形指示点

4.3 动画增强:弹性切换效果

4.4 复合指示:数字标签


引言

在现代移动应用和桌面软件中,分页式界面设计已成为主流的交互范式。Qt Quick Controls 2提供的PageIndicator控件,通过与SwipeView或TabBar的无缝集成,为开发者提供了开箱即用的分页指示解决方案。本文将深度解析该控件的使用技巧以及定制化实践方案。


1. PageIndicator特性

  • 动态页面感知:自动同步SwipeView/TabBar的页面数量(count)和当前位置(currentIndex)
  • 交互支持:支持点击指示点直接跳转目标页面
  • 自适应布局:根据容器尺寸自动调整指示点间距
  • 样式可定制:可完全自定义指示点形状、颜色和动画
  • 跨平台适配:遵循不同操作系统的设计规范

2. 基础实现:与SwipeView联动

2.1 基本示例

import QtQuick
import QtQuick.Controls

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    SwipeView {
        id: swipeView
        anchors.fill: parent
        currentIndex: pageIndicator.currentIndex

        Repeater {
            model: 5
            Page {
                Label {
                    text: "Page " + (index + 1)
                    anchors.centerIn: parent
                }
            }
        }
    }

    PageIndicator {
        id: pageIndicator
        anchors {
            bottom: parent.bottom
            horizontalCenter: parent.horizontalCenter
            bottomMargin: 20
        }
        count: swipeView.count
        currentIndex: swipeView.currentIndex
    }
}

代码解析

  • ​​​​​​通过Repeater生成5个测试页面
  • count属性绑定SwipeView的页面总数
  • 双向绑定currentIndex实现交互同步
  • 底部居中定位指示器

运行效果:


2. 交互增强版

import QtQuick
import QtQuick.Controls

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    SwipeView {
        id: swipeView
        anchors.fill: parent
        currentIndex: pageIndicator.currentIndex

        Repeater {
            model: 5
            Page {
                Label {
                    text: "Page " + (index + 1)
                    anchors.centerIn: parent
                }
            }
        }
    }

    PageIndicator {
        id: pageIndicator
        interactive: true  // 启用点击跳转
        anchors {
            bottom: parent.bottom
            horizontalCenter: parent.horizontalCenter
            bottomMargin: 20
        }
        count: swipeView.count
        currentIndex: swipeView.currentIndex
        delegate: Rectangle {
            implicitWidth: 16
            implicitHeight: 16
            radius: width/2
            color: index === pageIndicator.currentIndex ? "#21be2b" : "#e0e0e0"

            Behavior on color {
                ColorAnimation { duration: 200 }
            }
        }
    }
}

这是一个简单滑动页面的应用,包含5个页面和一个可交互的页面指示器。

要点:

  • 滑动视图:使用SwipeView实现页面滑动,包含5个页面,每个页面显示“Page x”。
  • 页面指示器:使用PageIndicator显示当前页面位置,支持点击跳转。
  • 交互设计:页面指示器的当前页圆点颜色为绿色,其他为灰色,颜色变化带有200ms的动画效果。
  • 布局:页面指示器位于窗口底部居中,距离底部20像素。

运行效果:


3. 属性介绍

属性类型默认值说明
countint0总页数,需手动绑定数据源
currentIndexint0当前激活页索引
spacingreal4指示点间距
interactiveboolfalse是否响应点击事件
orientationenumQt.Horizontal排列方向(Qt.Horizontal/Vertical)

4. 实践方案

4.1 动态页面管理(分页加载)

Column {
    anchors.fill: parent

    SwipeView {
        id: swipeView
        width: parent.width
        height: parent.height - 100
        currentIndex: pageIndicator.currentIndex

        // 动态加载复杂页面
        Repeater {
            model: ListModel {
                ListElement { component: "Page1.qml" }
                ListElement { component: "Page2.qml" }
                ListElement { component: "Page3.qml" }
            }
            Loader {
                active: SwipeView.isCurrentItem || SwipeView.isNextItem
                source: component
            }
        }
    }

    PageIndicator {
        id: pageIndicator
        count: swipeView.count
        currentIndex: swipeView.currentIndex
        anchors.horizontalCenter: parent.horizontalCenter
        y: swipeView.height + 20

        // 动态调整可见性
        visible: count > 1
    }
}

这段QML代码实现了一个可滑动的视图(SwipeView),通过动态加载多个页面(Page1.qml、Page2.qml、Page3.qml)并配合页面指示器(PageIndicator)来展示和切换页面。

  • 布局结构:使用Column作为根布局,确保SwipeView和PageIndicator垂直排列。
  • 动态加载:通过Repeater和Loader动态加载页面,减少内存占用,仅加载当前页面和下一个页面。
  • 页面指示器:PageIndicator的可见性根据页面数量动态调整,且其位置与SwipeView高度相关。

其中Page1、Page2、Page3分别为红色、绿色、蓝色矩形。 

Page1示例:

import QtQuick
import QtQuick.Controls

Rectangle {
    width: 100
    height: 100
    color: "red"
}

运行效果:


4.2 形状定制:菱形指示点

将2.1示例中的PageIndicator控件稍加改造:

PageIndicator {
    id: pageIndicator
    interactive: true  // 启用点击跳转
    anchors {
        bottom: parent.bottom
        horizontalCenter: parent.horizontalCenter
        bottomMargin: 20
    }
    count: swipeView.count
    currentIndex: swipeView.currentIndex

    // 动态调整可见性
    visible: count > 1

    delegate: Rectangle {
        width: 14
        height: 14
        rotation: 45  // 旋转45度形成菱形
        color: {
            if (index === swipeView.currentIndex)
                return "#ff9800"
            else
                return "#cccccc"
        }

        Behavior on color {
            ColorAnimation { duration: 150 }
        }
    }
}

指示器的每个元素是一个菱形的矩形,颜色会根据是否为当前页面动态变化,并且支持点击跳转。

要点:

  • 交互性:interactive: true,允许用户通过点击指示器跳转到对应的页面。
  • 布局和对齐:通过anchors设置,指示器位于父布局的底部,水平居中,并且底部有20像素的边距。
  • 动态可见性:visible属性根据页面数量动态调整,当页面数大于1时才显示。

指示器的视觉效果:

  • 每个指示器元素是一个旋转45度的矩形(形成菱形)。
  • 颜色根据是否为当前页面动态变化,当前页面为橙色(#ff9800),其他页面为灰色(#cccccc)。
  • 颜色变化通过ColorAnimation实现平滑过渡,持续时间为150毫秒。 

运行效果:


4.3 动画增强:弹性切换效果

PageIndicator {
    id: pageIndicator
    interactive: true  // 启用点击跳转
    anchors {
        bottom: parent.bottom
        horizontalCenter: parent.horizontalCenter
        bottomMargin: 20
    }
    count: swipeView.count
    currentIndex: swipeView.currentIndex

    // 动态调整可见性
    visible: count > 1

    delegate: Item {
        width: 20
        height: 20

        Rectangle {
            id: dot
            anchors.centerIn: parent
            width: parent.width * (index === swipeView.currentIndex ? 0.8 : 0.6)
            height: width
            radius: width/2
            color: "#2196f3"

            Behavior on width {
                NumberAnimation {
                    duration: 300
                    easing.type: Easing.OutBack
                }
            }
        }
    }
}

delegate部分定义了页面指示器中每个指示点的样式和动画效果,指示点为圆形,当前页面的指示点会放大并带有弹性动画效果。

要点:

  • 指示点布局:每个指示点是一个Item,宽度和高度均为20像素。
  • 圆形指示点:通过Rectangle定义指示点,使用radius属性使其呈现圆形。

动态变化:

  • 当前页面的指示点会放大到父元素宽度的80%,其他页面的指示点为60%。
  • 尺寸变化通过NumberAnimation实现,持续时间为300毫秒,带有弹性效果(Easing.OutBack)。

运行效果:


4.4 复合指示:数字标签

PageIndicator {
    id: pageIndicator
    interactive: true  // 启用点击跳转
    anchors {
        bottom: parent.bottom
        horizontalCenter: parent.horizontalCenter
        bottomMargin: 20
    }
    count: swipeView.count
    currentIndex: swipeView.currentIndex

    // 动态调整可见性
    visible: count > 1

    delegate: Column {
        spacing: 5

        Rectangle {
            width: 12
            height: 12
            radius: 6
            color: index === swipeView.currentIndex ? "green" : "gray"
        }

        Text {
            text: index + 1
            color: "#333"
            font.bold: true
            anchors.horizontalCenter: parent.horizontalCenter
        }
    }
}

delegate部分定义了页面指示器中每个指示项的样式,每个指示项由一个圆形矩形和一个数字文本组成,圆形的颜色根据是否为当前页面动态变化。

在之前的例子上新增了数字文本:

  • 显示当前页面的索引加1(index + 1),表示页面编号。
  • 文本颜色为深灰色("#333"),字体加粗。

运行效果:


参考:PageIndicator QML Type | Qt Quick Controls 6.8.2

相关文章:

  • 【重构小程序】基于Tika和Langchain4J进行文件解析和文本切片(二)
  • 自然语言处理(Natural Language Processing,NLP)入门教程
  • AfxMessageBox()和MessageBox()的差异。
  • OpenCV旋转估计(2)用于自动检测波浪校正类型的函数autoDetectWaveCorrectKind()
  • T-CSVT投稿记录
  • Century Avenue?有限元 lsdyna ansys、でしょ?
  • 【QA】观察者模式在QT有哪些应用?
  • 【Linux篇】进程控制
  • Pytest的夹具
  • 夸克网盘突破限速下载
  • 【MySQL】内置函数
  • 11 python 数据容器-字符串
  • 面试题精选《剑指Offer》:JVM类加载机制与Spring设计哲学深度剖析-大厂必考
  • 九、JavaScript作用域、预解析
  • 【数据分享】2000—2024年我国乡镇的逐月归一化植被指数(NDVI)数据(Shp/Excel格式)
  • 遇到一个奇怪问题,页面请求不到后端
  • 基于SpringBoot+Vue3实现的宠物领养管理平台功能七
  • 95 克的工业级动能:STONE 80A-M 电调深度测评 —— 无人机动力系统的轻量化范式
  • 跨域问题确认及处理
  • windows10在wsl上利用GPU运行tensorflow 2.12
  • 4月中国常青游戏榜:32款游戏吸金近34亿元,腾讯、网易占半壁江山,《原神》再跌出前十
  • 上海国际电影节将于6月3日公布排片表,6月5日中午开票
  • 遇见东方:18世纪俄罗斯宫殿中的“中国风”
  • 外交部:巴基斯坦副总理兼外长达尔5月19日至21日访华
  • 证监会披露两起操纵市场处罚结果,今年来涉操纵股票罚没金额超7.5亿元
  • 《缶翁的世界》首发:看吴昌硕等湖州籍书画家的影响