qwt实现码流柱状图多色柱体显示

qwt实现码流柱状图多色柱体显示

  • 1. 前言
  • 2. qt实现柱状图
  • 3.qwt基础说明
    • 3.1 qwt安装与使用
      • 3.1.1 下载qwt源码
      • 3.1.2 编译
      • 3.1.3 安装
      • 3.1.4 使用
    • 3.2 QwtPlotBarChart类
      • 3.2.1画图步骤
      • 3.2.2 specialSymbol
      • 3.3.3 barTitle
  • 4 BsBarChart定制
    • 4.1 每个柱体可以显示不同的颜色
    • 4.2 每个柱体可以显示对应的数值
    • 4.3 每个柱体的坐标显示不同的信息
    • 4.4 实现滚动拉动滚动条显示剩余的柱体
    • 4.5 单击/hover时,对应柱体显示想要的字符串
    • 4.6 单击选项,可以跳转到对应的柱体
  • 5 总结

1. 前言

在视频码流分析中,经常用到elecard 来查询码流的参考关系,其中就有柱状图来表示每一帧的示意图,如:
 图1

在工作之余,想通过Qt实现一款自己的码流分析工具,实现这个工具需要了解视频的一些概念,在此文章中不展开讲述,本文主要是讲述qt实现多色柱状图,以及一些定制化实现。简单的demo如下:
图2

功能:

1.每个柱体可以显示不同的颜色

2.每个柱体可以显示对应的数值

3.每个柱体的坐标显示不同的信息

4.实现滚动拉动滚动条显示剩余的柱体

5.单击/hover柱体,显示想要的字符串

6.单击选项,可以跳转到对应的柱体

2. qt实现柱状图

qt实现柱状图有多种方法,例如QChart, Qwt, QCustomPlot,甚至可以自己手搓,关于这三者的对比可以网上查询一些参考,个人觉得如果是实现一些简单的图表类,可以使用QChart,上手快,外观较其他两个漂亮,但在一些定制化中,却不够友好,而qwt就相对容易实现复杂的定制化,想要设计得很漂亮也可以,但需要比较深入研究,QCustomPlot源码就两个文件,可以方便集成到项目里,但由于不够成熟,对于一些复杂的画图,要自己实现很多功能。

为了实现图1的效果,本人一开始使用QtChart做,但最后发现,每个柱体要显示不同的颜色,会使用大量的内存,这个是不划算的,最后综合考虑下,使用qwt实现。

3.qwt基础说明

3.1 qwt安装与使用

这章内容在网络上有许多介绍,但有些作者在一些地方没有描述清楚,下面简略介绍下步骤:

本人的环境是:

pc: window 10

qt: qt5.9.8+mingw53_32

3.1.1 下载qwt源码

  1. sourceforge地址:
    release包:https://sourceforge.net/projects/qwt/files/qwt/
    git方式:https://sourceforge.net/p/qwt/git/ci/develop/tree/
  2. github地址:https://github.com/opencor/qwt
  3. wiki地址:https://qwt.sourceforge.io/

从上面的地址任意一个下载源码,如果后续需要研究源码,建议通过git下载仓库,方便回溯

3.1.2 编译

  • 最简单的是通过QtCreator打开qwt的工程,一键编译

  • 或者使用命令行方式,用qmake编译

编译模式选择:

选择release模式,这样编译出来的库size小一点,另外如果需要在qtdesigner,qtcreator上实现画图,需要用到release版本

当然debug,profile版本也是可以的,就是后续在发布软件时,size会大很多,发布软件一版都是release版本的库。

编译出来结果如下:
图3

3.1.3 安装

为了后续可以在qtcreator,qtdesiner上画图,就需要将编译出来的库,头文件,画图插件拷贝到qt的安装目录下:

将编译出来的designer\plugins\designer文件夹下的qwt_designer_plugin.dll放到C:\Qt\Qt5.9.8\5.9.8\mingw53_32\plugins\designer

另外,也需要:

  1. 将编译出来的lib文件夹下的libqwt.a,libqwtd.a放到C:\Qt\Qt5.9.8\5.9.8\mingw53_32\lib
  2. 将编译出来的lib文件夹下的qwt.dll,qwtd.dll放到C:\Qt\Qt5.9.8\5.9.8\mingw53_32\bin
  3. 将qwt源码目录下src里的*.h头文件全部拷贝到C:\Qt\Qt5.9.8\5.9.8\mingw53_32\include\Qwt,Qwt文件夹需要自行创建

3.1.4 使用

  1. 在工程中使用qwt,需要在*.pro文件里添加qwt的库和头文件链接,方法可以手动添加,也可以在pro文件里右键选择外部库路径
  2. 对于一份可移植的工程来说,一般做法是不链安装在qt目录下载qwt库的,应该在工程文件里创建一个文件夹,放置qwt的头文件和库,这样别人用的时候,就不需要额外去编译qwt。而且也可以放置多份不同的编译工具链编译出来的库,例如32位,64位的,这样就可以在不同平台中进行编译自己的code,而且发布软件时,也可以根据不同的平台进行发布
  3. 拖拽画图,如果qwt编译使用mingw53编译,那么只能在qtdesigner里打开进行画图,因为qtcreator是用mvsc编译的,qwt_designer_plugin.dll不匹配,方法是在打开的qtcreator工程里,在ui文件处右键,选择用qtdesigner打开。

3.2 QwtPlotBarChart类

qwt源码中有自带的example例子,可以参考来实现examples\distrowatch
图4

该例子已经可以实现每个柱体不同颜色,但跟所想要的效果还差很多功能,以下定制,是基于此开发的。

在此之前,需要先说明下,qwt的barChart的画图原理:
图5

  1. 高度:橙色蓝色两个柱体高度分别是1,2。

  2. 柱体位置:柱体的中间位置对应着坐标点

  3. 宽度:柱体的宽度默认是1,即两个柱体间应该紧密挨着,中间没有空隙,但可以通过QwtPlotBarChart的setLayoutHint,setSpacing来调节柱体的间的空隙。

    全部柱体的宽度平均分配整个画布宽度的大小,例如,画布大小是400宽度,一共4个柱体,那么每个柱体应该是100宽度。对应箭头1,宽度也是100。

    当通过setLayoutHint设置柱体的宽度,例如设置了20宽度,则箭头2是20宽度,箭头3空隙就是80,箭头4宽度是10,但箭头1还是100。

    setSpacing函数,设置箭头3的宽度

    箭头2+箭头3=箭头1

    箭头4=箭头2的一半

  4. 坐标:以柱体的左上角的坐标为例

    相对于整个画布的位置,分别是(-0.5,1),(0.5,2)

    相当于pc窗口来说,分别是(100,50),(101,51)

    画布坐标和pc窗口坐标的转换,通过mapToGlobal函数来转换

3.2.1画图步骤

如果没有任何定制化需求,QwtPlotBarChart在调用时,就两个步骤:

  • new一个QwtPlotBarChart实例

  • 调用setSamples传递数据

这样就能生成柱状图(当然plot, cavas还是要创建的),QwtPlotBarChart类内部会自动画出默认格式的

3.2.2 specialSymbol

而当需要定制不同的柱体(不包括图例,下标等定制),就需要实现重载函数:

virtual QwtColumnSymbol* specialSymbol(int sampleIndex, const QPointF& ) const;

qwt的QwtPlotBarChart类中的specialSymbol函数是一个空函数,如果需要实现定制化,可以继承QwtPlotBarChart,自行实现此函数,该函数里有参数smpleIndex,可见是可以对具体的某个特定柱体实现特定的定制的。

qwt源码中QwtPlotBarChart类的specialSymbol函数是一个空函数:

QwtColumnSymbol* QwtPlotBarChart::specialSymbol(int sampleIndex, const QPointF& sample ) const
{Q_UNUSED( sampleIndex );Q_UNUSED( sample );return NULL;
}

当在画柱体时,drawBar函数:

void QwtPlotBarChart::drawBar( QPainter* painter,int sampleIndex, const QPointF& sample,const QwtColumnRect& rect ) const
{const QwtColumnSymbol* specialSym =specialSymbol( sampleIndex, sample );const QwtColumnSymbol* sym = specialSym;if ( sym == NULL )sym = m_data->symbol;if ( sym ){sym->draw( painter, rect );}else{// we build a temporary default symbolQwtColumnSymbol columnSymbol( QwtColumnSymbol::Box );columnSymbol.setLineWi

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1559284.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

MFC项目如何使用hiredis库连接redis

如何在windows平台使用c连接redis 1. 下载hiredis的vs工程文件2. 使用vs2022编译hiredis3.项目中调用4. 集群连接5. 简单的封装下 最近需要在windows PC终端读取redis数据。我这里使用hiredis连接redis. 工程是vs2022开发的。 1. 下载hiredis的vs工程文件 windows平台需要自己…

【C/C++】错题记录(七)

题目一 题目二 C在调用函数时,当实参和形参的数据类型不一致时,会发生数据类型转换!将低精度转换为高精度时,由编译器隐式完成;将高精度转换为低精度时,必须用强制类型转换运算符; static_cast…

Redis:分布式 - 哨兵

Redis:分布式 - 哨兵 概念哨兵 Docker 搭建哨兵分布式选举流程 概念 Redis 的主从复制模式下,一旦主节点由于故障不能提供服务,需要人工进行主从切换,同时大量的客户端需要被通知切换到新的主节点上,对于上了一定规模…

浏览器动态移动的小球源码分享

浏览器动态移动的小球源码分享 <script>(function(a){var width100,height100,borderRadius100,circlefunction(){};circle.prototype{color:function(){let colour "#"Math.floor(Math.random()*255).toString(16)Math.floor(Math.random()*255).toString…

Linux块设备驱动实验

直接参考【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81 本文仅作为个人笔记使用&#xff0c;方便进一步记录自己的实践总结。 前面我们都是在学习字符设备驱动&#xff0c;本章我们来学习一下块设备驱动框架&#xff0c;块设备驱动是Linux 三大驱动类型之一。块设备驱动要远…

Fiddler配合wireshark解密ssl

环境&#xff1a; win11&#xff08;wireshark&#xff09;--虚拟机win7&#xff08;Fiddler&#xff09;---虚拟机win7&#xff08;HTTPS站点&#xff09; 软件安装问题&#xff1a; 需要.net环境&#xff0c;NDP461-KB3102436-x86-x64-AllOS-ENU.exe。 安装fiddler后安装下…

vite项目打包md5报‘default‘ is not exported错误的解决方法

报错如下&#xff1a; 某一个包中用es方式引入md5模块&#xff0c;导致打包报错&#xff0c;经过一番探究测试&#xff0c;发现我的项目中用了“vite-plugin-require-transform”这个插件&#xff0c;是这个插件在做转换的时候报错了&#xff0c;如果你也是这个原因可按我的方式…

代码随想录day24:贪心part2

121. 买卖股票的最佳时机 class Solution {public int maxProfit(int[] prices) {int ans 0;int minPrice prices[0];for(int p : prices){ans Math.max(ans, p - minPrice);minPrice Math.min(p, minPrice);}return ans;} } 运用前缀和思想&#xff0c; 从左到右枚举卖…

Spring Boot教学资源库:构建微服务的基石

2 相关技术简介 2.1Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;任…

dart-sass和node-sass的区别,使用dart-sass后可能会出现的问题

前言&#xff1a; 2020 年 10 月 27 日&#xff0c;Sass 官方团队正式宣布 Libsass 将弃用&#xff0c;以及基于它的 Node Sass 和 SassC&#xff0c;并且建议用户使用 Dart Sass。如果在 vue 脚手架搭建的项目中需要使用 sass&#xff0c;建议初始化时勾选 sass 配置&#xff…

前端优化之路:git commit 校验拦截

但是想要做到高效落地执行&#xff0c;就需要做些别的功课&#xff0c;先展示下成果图 需要了解git hooks&#xff0c;它是git的钩子&#xff0c;就像vue拥有自己的钩子一样。 官方文档&#xff1a;https://git-scm.com/docs/githooks 项目安装 husky&#xff0c;建议稳定版本…

patch函数前两个参数位

如我们多了解的&#xff0c;patch函数前两个参数位为 oldVnode 和 Vnode &#xff0c;分别代表旧节点和新节点&#xff0c;主要做了四个判断&#xff1a; patchVnode主要做了两个判断&#xff1a;

java中Math类和Random类的api

目录 Math 类 1&#xff09;abs(x) 2&#xff09;ceil(x) 3&#xff09;floor(x) 4&#xff09;round(x) 5&#xff09;max(x, y) 6&#xff09;min(x, y) 7&#xff09;sqrt(x) 8&#xff09;pow(x, y) 9&#xff09;random() 10&#xff09;sin(x), cos(x), tan(x) 11&#x…

购物网站毕业设计-电子电器商城管理系统SpringBootSSM框架开发

目录 1. 系统概述 1.1背景介绍 1.2 课题意义 1.3课题目标 2. 主要功能模块 2.1 前端用户模块 2.2 后端管理模块 2.3 功能图展示 3. 技术选型 3.1 VUE介绍 3.2 JAVA介绍 3.3 MySQL介绍 4. 系统设计 4‌.1数据库设计 5 详细设计 5.1 界面展示 设计一个电子电…

通过Keil5编译软件获取函数最深堆栈

文章目录 1.问题提出2.问题分析3.环境搭建4.解决方案5.经验总结6.疑问 1.问题提出 在编写新软件时&#xff0c;由于某功能需要使用RAM约24KB&#xff0c;而新模块的总RAM是96KB&#xff0c;该某功能一旦开启则需要占用四分之一的RAM空间。为了保证在开启某功能后&#xff0c;新…

WPF中的Window类

控件分类 在第一篇文章.Net Core和WPF介绍中的WPF的功能和特性部分根据功能性介绍了WPF的控件 名称。 在接下来的文章中&#xff0c;将会详细的介绍各个控件的概念及使用。 主要包括&#xff1a; 内容控件&#xff1a;Label、Button、CheckBox、ToggleButton、RadioButton、…

高性能缓存方案 —— Caffeine

一、简介 Caffeine是一个高性能的Java缓存库&#xff0c;它提供了本地缓存的功能。 Caffeine和Redis都是内存级别的缓存&#xff0c;为什么要使用在这两缓存作为二级缓存&#xff0c;它们两有什么区别呢? 虽然它们都是内存级别的缓存&#xff0c;但是Redis是需要单独部署的&…

【开源风云】从若依系列脚手架汲取编程之道(五)

&#x1f4d5;开源风云系列 &#x1f34a;本系列将从开源名将若依出发&#xff0c;探究优质开源项目脚手架汲取编程之道。 &#x1f349;从不分离版本开写到前后端分离版&#xff0c;再到微服务版本&#xff0c;乃至其中好玩的一系列增强Plus操作。 &#x1f348;希望你具备如下…

鸿蒙OS投票机制

(基于openharmony5.0) 投票机制 param get | grep ohos.boot.time 图 投票机制参数图 只有当所有的投票完成&#xff0c;开机动画才会退出&#xff0c;整理需要投票的系统应用&#xff08;三方应用不参与投票&#xff09;如下图所示&#xff1a; 以进程foundation为例&…

Python案例--copy复制

在Python编程中&#xff0c;数据的复制是一个常见且重要的操作&#xff0c;它涉及到赋值、浅拷贝和深拷贝三种不同的概念。正确理解这三种操作对于编写高效且正确的程序至关重要。本文将通过一个简单的Python示例&#xff0c;探讨这三种数据复制方式的区别及其应用场景&#xf…