首页 > 其他分享 >Qml 中实现时间轴组件

Qml 中实现时间轴组件

时间:2025-01-16 11:47:23浏览次数:1  
标签:样式 timestamp listModel content 时间轴 组件 Qml

【写在前面】

时间轴组件是现代用户界面中常见的元素,用于按时间顺序展示事件。

本文将介绍如何使用 Qml 实现一个灵活且可定制的时间轴组件,并探讨其设计思路和实现细节。


【正文开始】

效果图

组件概述

我们实现的时间轴组件具有以下特点:

  1. 支持自定义节点样式:可以设置节点的图标、背景颜色、边框颜色等。
  2. 支持自定义线条样式:可以设置线条的颜色和宽度。
  3. 支持自定义时间显示格式:可以设置时间的显示格式和字体样式。
  4. 支持自定义内容样式:可以设置内容的背景颜色、边框颜色、字体样式等。
  5. 支持正序和倒序排列:可以根据时间戳对事件进行正序或倒序排列。

实现细节

1. 组件结构

时间轴组件的核心是一个 ListView,它用于展示所有的事件项。每个事件项由三个部分组成:

  • 节点:表示事件的时间点,可以是图标或圆形背景。
  • 线条:连接相邻事件的节点。
  • 内容:显示事件的具体内容和时间。
2. 属性定义

组件提供了多个属性来定制时间轴的外观和行为:

  • 节点样式defaultNodeIconColordefaultNodeBackgroundRadiusdefaultNodeBackgroundColordefaultNodeBorderColordefaultNodeBorderWidth
  • 线条样式defaultLineColordefaultLineWidth
  • 时间样式defaultTimeFontdefaultTimeFontColordefaultTimeFormat
  • 内容样式defaultContentFormatdefaultContentFontdefaultContentFontColordefaultContentBackgroundRadiusdefaultContentBackgroundColordefaultContentBorderColordefaultContentBorderWidth
3. 数据模型

时间轴组件使用 ListModel 来存储事件数据。每个事件项包含以下属性:

  • timestamp:事件的时间戳。
  • content:事件的内容。
  • nodeOptions:节点的样式选项。
  • lineOptions:线条的样式选项。
  • timeOptions:时间的样式选项。
  • contentOptions:内容的样式选项。
4. 事件项的添加和排序

组件提供了 append 函数来添加新的事件项,并根据时间戳进行排序。sort 函数用于对现有的事件项进行重新排序。

function append(object) {
    __initOptions(object);

    let index = 0;
    let rowCount = listModel.count;
    for (let i = 0; i < rowCount; i++) {
        if (root.reverse) {
            if (listModel.get(i).__timestamp < object.__timestamp) {
                index = i + 1;
            } else break;
        } else {
            if (listModel.get(i).__timestamp > object.__timestamp) {
                index = i + 1;
            } else break;
        }
    }
    listModel.insert(index, object);
}

function sort() {
    let rowCount = listModel.count;
    for (let i = 0; i < rowCount; i++) {
        for (let j = 0; i + j < rowCount - 1; j++) {
            if (root.reverse) {
                if (listModel.get(j).__timestamp > listModel.get(j + 1).__timestamp) {
                    listModel.move(j, j + 1, 1);
                }
            } else {
                if (listModel.get(j).__timestamp < listModel.get(j + 1).__timestamp) {
                    listModel.move(j, j + 1, 1);
                }
            }
        }
    }
}
5. 事件项的渲染

每个事件项通过 Loader 动态加载节点、线条和内容组合组件:

Loader {
    id: lineLoader
    active: index !== (listModel.count - 1)
    width: nodeLoader.width
    height: parent.height - nodeLoader.height
    anchors.top: nodeLoader.bottom
    sourceComponent: lineDelegate
    property var lineOptions: __lineOptions
}

Loader {
    id: nodeLoader
    sourceComponent: nodeDelegate
    property var nodeOptions: __nodeOptions
}

Loader {
    id: contentLoader
    anchors.left: nodeLoader.right
    anchors.leftMargin: 10
    anchors.right: parent.right
    sourceComponent: contentDelegate
    property var content: __content
    property var contentOptions: __contentOptions
    property var timestamp: __timestamp
    property var timeOptions: __timeOptions
}

如何使用

我们可以像使用标准的 qml 元素一样使用时间轴组件:

import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 800
    height: 600
    title: "Timeline Example"

    Timeline {
        id: timeline
        width: 400
        anchors.top: row.bottom
        anchors.topMargin: 10
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        defaultNodeBackgroundColor: "transparent"
        defaultNodeBorderWidth: 1
        defaultTimeFormat: "yyyy-MM-dd hh:mm:ss"
        initModel: [
            {
                timestamp: new Date(2024, 7, 1, 1),
                content: "更新 Github 模板 1",
                nodeOptions: { icon: "\uf27b" }
            },
            {
                timestamp: new Date(2024, 7, 7, 11),
                content: "更新 Github 模板 2",
                nodeOptions: { backgroundColor: "blue" },
                lineOptions: { color: "red" }
            },
            {
                timestamp: new Date(2024, 7, 7, 16),
                content: "更新 Github 模板 2",
                lineOptions: { width: 5 }
            },
            {
                timestamp: new Date(2024, 7, 9, 5, 30),
                content: "更新 Github 模板 3"
            },
            {
                timestamp: new Date(2024, 7, 12, 9),
                timeOptions: {
                    font: { family: "华文彩云", pointSize: 12 },
                    fontColor: "green",
                    format: "yyyy-MM-dd hh:mm:ss:zzz"
                },
                content: "更新 Github 模板 4",
            },
            {
                timestamp: new Date(2024, 7, 12, 18, 30),
                content: "更新 Github 模板 5",
                contentOptions: {
                    font: { family: "微软雅黑", pointSize: 14 },
                    fontColor: "red",
                    backgroundColor: "#ddd"
                }
            },
            {
                timestamp: new Date(2024, 7, 17, 5, 35),
                content: "更新 Github 模板 6 ===================================",
                contentOptions: {
                    borderColor: "#ddd"
                }
            }
        ]
    }
}

【结语】

通过自定义 Qml 组件,我们实现了一个灵活且可定制的时间轴组件。

该组件不仅支持基本的时间轴功能,还提供了丰富的样式定制选项,能够满足各种实际开发需求。

最后:项目链接(多多star呀..⭐_⭐):

Github: https://github.com/mengps/QmlControls

Gitee: https://gitee.com/MenPenS/QmlControls

标签:样式,timestamp,listModel,content,时间轴,组件,Qml
From: https://www.cnblogs.com/mengps/p/18674699

相关文章

  • vue2子组件获取父组件的实例以及数据,vue2子组件获取父组件的数据
    多个组件引入同一个js文件,实例化对象,数据不会错乱,再引入相同的组件,例如每个页面都需要引入到一个分页组件,然后分页组件需要获取各自父组件中的实例对象通过  this.$parent 即可获取到父组件中的数据所以在使用子组件时可以不用在组件上传入数据 公共js文件functionda......
  • Windows 可靠多播传输驱动程序(RMCAST) 是 Windows 操作系统中负责支持和管理可靠多播(Re
    CVE-2025-21307漏洞是Windows可靠多播传输驱动程序(RMCAST)中的远程代码执行漏洞。该漏洞允许未经身份验证的攻击者在受影响的系统上执行任意代码,可能导致系统被完全控制。漏洞描述:该漏洞存在于Windows可靠多播传输驱动程序(RMCAST)中。攻击者可以通过发送特制的请求......
  • WPF冷却塔组件
    1.封装基类ComponentBase.cs继承自UserControl,定义组件中使用的属性和命令publicclassComponentBase:UserControl{privatebool_isSelected;publicboolIsSelected{get{return_isSelected;}set{_isSelecte......
  • vue组件大全
    作用此随笔记录我人生中所有自己写出来的组件样式图片加文字组件<template><divclass="set_img"><el-container><el-asidewidth="300px"><pclass="set_img_p">弹框一:</p>......
  • 封装按钮信息与按钮数量动态显示与提示信息并进行触发按钮组件
    标题:封装弹框并点击动态按钮组件进行触发功能:封装按钮信息与按钮数量动态显示组件页面:按钮信息与按钮数量动态显示,提示信息不固定封装组件页面: <template><el-dialogv-model="dialogVisible"class="stepCustom-dialogcustom-dialog-center"destroy-on-closeheight=......
  • 图表封装组件
    图表封装: 图表封装使用:<template><!--软件模块复用率图表--><chart-and-tableref="chartAndTableRef":chart-desc="chartDesc":chart-loading="chartLoading":columns="columns":list="list":......
  • vuex 构建多组件共享的数据环境
    Vuex是Vue.js的官方状态管理库,用于在Vue.js应用程序中构建多个组件共享的数据环境。Vuex可以帮助我们解决组件之间共享数据和状态管理的问题。它将应用程序的状态存储在一个单一的地方,称为"store",并且允许组件直接从store中获取和修改状态,而不需要通过事件或属性传递......
  • 《鸿蒙开发-鸿蒙教程-答案之书》组件margin左和右等于没偏?
    《鸿蒙开发-鸿蒙教程-答案之书》组件margin左和右等于没偏?鸿蒙的margin和Android的margin还是有点区别,Android的margin没有任何毛病,但是鸿蒙margin会导致组件偏移回来的。因为鸿蒙的组件可以超越父组件,往外面宽展。那怎么办呢?先看个有问题的代码:@Entry@Componentstruc......
  • Vue.js组件开发-使用地图绘制轨迹
    在Vue.js中开发一个组件来展示地图并绘制轨迹,可以使用诸如Leaflet.js、MapboxGLJS或百度地图等地图库。这些库提供了丰富的API来创建和定制地图,以及绘制路径、标记和其他地图元素。示例:1.安装Leaflet.js首先,需要安装Leaflet.js库。可以通过npm或yarn来安装:npminstalll......
  • 深度剖析RabbitMQ:从基础组件到管理页面详解
    文章目录一、简介二、Overview2.1Overview->Totals2.2Overview->Nodesbroker的属性2.3Overview->Churnstatistics2.4Overview->Portsandcontexts2.5Overview->Exportdefinitions2.6Overview->Importdefinitions三、Connections连接的属性四、Channels通道的......