QT创造一个新的类(柱状图的类),并关联属性和方法

news2024/12/24 3:39:13

1.以在UI上添加柱状图的类为例(Histogram)

#ifndef STUDY_HISTOGRAM_H
#define STUDY_HISTOGRAM_H


#include <QVector>
#include <QWidget>

// 前向声明
QT_BEGIN_NAMESPACE
class QColor;
class QRect;
class QString;
class QPaintDevice;
QT_END_NAMESPACE

class Study_HistogramItem
{
public:
    QString m_Name;
    qreal	m_Value;
    QColor	m_PillarColor;
    QRect	m_PillarRect;
};



class Study_Histogram : public QWidget
{
    public:
        Study_Histogram( QWidget* parent = 0 );

        //方法
        void Study_AddItem( QString name, qreal value,
                      QColor pillarColor );
        void Study_SetMaxValue( quint32 maxValue );	// 设置最大值,以便绘图
        void Study_Clear();   // 清空所有已添加的Item

        void Study_Paint( QPaintDevice* pDevice );	// 绘图

    protected:
        //刷新页面
        void paintEvent(QPaintEvent *);

    private:
        void Study_DrawAxis( QPaintDevice* pDevice, QPainter* pPainter );     // 绘制坐标轴
        void Study_DrawPillars( QPaintDevice* pDevice, QPainter* pPainter );	// 绘制柱子
        void Study_DrawText( QPainter *pPainter );		// 绘制文字
        void Study_DrawScale( QPaintDevice* pDevice, QPainter* pPainter );	// 绘制刻度

        //类属性
        enum Study_HistogramOptions
        {
            blankWidth		= 64,		// 两个柱子间的空格大小
            pillarIndent	= 0,		// 首个柱子缩进的大小
            xAxisOffset		= 16,		// X轴的偏移(相对于左边界)
            yAxisOffset		= 16,		// Y轴的偏移(相对于下边界)
            textRectHeight	= 32		// 文字矩形框的高
        };

        qreal							m_Study_axValue;
        QVector<Study_HistogramItem>			m_Study_VecItems;

};

#endif // STUDY_HISTOGRAM_H

2.饼图的属性:最大值,单个柱形的信息
在饼图类的构造函数中设置默认的信息:清空之前的柱形组数据


Study_Histogram::Study_Histogram(QWidget *parent)
{
    m_Study_VecItems.clear( );
}

3.饼图的方法(函数):添加柱形,设置最大值,清空信息
添加柱形:

void Study_Histogram::Study_AddItem(QString name, qreal value, QColor pillarColor)
{
    //先创建一个柱状信息的实例
    Study_HistogramItem item;
    item.m_Name			= name;
    item.m_Value		= value;
    item.m_PillarColor	= pillarColor;
    item.m_PillarRect	= QRect( );
    //将此实例添加到属性QVector中
    m_Study_VecItems.push_back( item );
}

设置最大值:

void Study_Histogram::Study_SetMaxValue(quint32 maxValue)
{
    //将参数传入类属性中
    m_Study_maxValue = maxValue;
}

清空信息:

void Study_Histogram::Study_Clear()
{
    //把柱状图信息容器清空
    m_Study_VecItems.clear();
}

4.某些属性的关联数据(单个柱形信息包括:名字,数据,颜色等)

在类的定义.h文件中,定义了结构体Study_HistogramItem
供给属性QVector<Study_HistogramItem>			m_Study_VecItems;

5.paintEvent进行自动刷新

void Study_Histogram::paintEvent(QPaintEvent *)
{
    Study_Paint(this);
}

void Study_Histogram::Study_Paint(QPaintDevice *pDevice)
{
    QPainter painter( pDevice );    //
    Study_DrawAxis( pDevice, &painter );// 绘制坐标轴
    Study_DrawPillars( pDevice, &painter );// 绘制柱子
    Study_DrawText( &painter );// 绘制文字
    Study_DrawScale( pDevice, &painter );// 绘制刻度
}

绘制坐标轴/柱子/文字/刻度(pPainter->drawText)


void Study_Histogram::Study_DrawAxis(QPaintDevice *pDevice, QPainter *pPainter)
{
    //坐标轴
    pPainter->drawLine( yAxisOffset, 0, yAxisOffset, pDevice->height( ) );
    pPainter->drawLine( 0, pDevice->height( ) - xAxisOffset,
                        pDevice->width( ), pDevice->height( ) - xAxisOffset );
}

void Study_Histogram::Study_DrawPillars(QPaintDevice *pDevice, QPainter *pPainter)
{
    //柱子
    if ( m_Study_VecItems.size( ) == 0 ) return;

    //const quint32 blankWidth = 64;		// 柱子间空格宽
    quint32 pillarWidth = ( pDevice->width( ) - yAxisOffset - pillarIndent
                            - quint32( m_Study_VecItems.size( ) - 1 ) * blankWidth )
            / m_Study_VecItems.size( );		// 柱子的宽

    // 绘制因子。绘制因子在绘制柱子的时候起着重要作用。
    // 根据比例公式:
    // pDevice->width( ) - xAxisOffset         pillarHeight
    // --------------------------------- = --------------------
    //              MaxValue                m_VecItem[0].value
    // 求出pillarHeight的值,但是左边的部分我们可以看作是一个绘制因子heightFact记录下来。
    // 计算时可以节约时间。
    qreal heightFact = qreal( pDevice->height( ) - xAxisOffset ) / m_Study_maxValue;

    for ( int i = 0; i < m_Study_VecItems.size( ); ++i )
    {
        quint32 pillarHeight = m_Study_VecItems[i].m_Value * heightFact;
        int leftUpX = yAxisOffset + pillarIndent + i * ( pillarWidth + blankWidth );
        int leftUpY = pDevice->height( ) - xAxisOffset - pillarHeight;
        QRect& rect = m_Study_VecItems[i].m_PillarRect;

        rect.setRect( leftUpX, leftUpY, pillarWidth, pillarHeight );
        pPainter->setPen( QPen( m_Study_VecItems[i].m_PillarColor ) );
        pPainter->setBrush( QBrush( m_Study_VecItems[i].m_PillarColor ) );
        pPainter->drawRect( rect );
    }

}

void Study_Histogram::Study_DrawText(QPainter *pPainter)
{
    // 已经可以保证m_VecItems.[i].m_Rect.isNull( )为假
    // 即柱子所在的矩形框是一个有效的矩形框
    pPainter->setPen( QPen( QColor( 0, 0, 0 ) ) );
    for ( int i = 0; i < m_Study_VecItems.size( ); ++i )
    {
        QRect rect( m_Study_VecItems[i].m_PillarRect.left( ) - blankWidth / 2,
                    m_Study_VecItems[i].m_PillarRect.top( ) - textRectHeight,
                    m_Study_VecItems[i].m_PillarRect.width( ) + blankWidth,
                    textRectHeight );

        const QString& text = QString( "%1(%2)" )
                .arg( m_Study_VecItems[i].m_Name ).arg( m_Study_VecItems[i].m_Value );
        pPainter->drawText( rect, Qt::AlignCenter, text );
    }
}

void Study_Histogram::Study_DrawScale(QPaintDevice *pDevice, QPainter *pPainter)
{
    // 名词解释 MSWidth = Marked Scale Width,刻度宽
    // MSHeight = Marked Scale Height 刻度高
    const quint32 MSWidth			= 100;
    const quint32 MSHeight			= textRectHeight;
    const quint32 heightInterval
            = ( pDevice->height( ) - xAxisOffset ) / 4;

    for ( int i = 0; i < 4; ++i )
    {
        QRect rect( 0,
                    i * heightInterval,
                    MSWidth,
                    MSHeight );
        pPainter->drawLine( yAxisOffset - 2,
                            i * heightInterval,
                            yAxisOffset + 2,
                            i * heightInterval );
        pPainter->drawText(
                    rect, Qt::AlignLeft, QString( "%1" )
                    .arg( m_Study_maxValue * ( 4 - i ) / 4 ) );
    }
}

使用:直接用ui -> …(提升的UI名) -> 类方法,此处ui->widget_histogram已经在UI中提升为Study_Histogram

    ui->widget_histogram->Study_SetMaxValue(100);

    ui->widget_histogram->Study_AddItem("name1",35,"red");
    ui->widget_histogram->Study_AddItem("name2",45,"green");
    ui->widget_histogram->Study_AddItem("name3",55,"black");
    ui->widget_histogram->Study_AddItem("name4",75,"red");

效果:
在这里插入图片描述

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

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

相关文章

适用于 macOS 的最佳独立 HBO Max 客户端

适用于 macOS 的最佳独立 HBO Max 应用程序。不再在浏览器选项卡之间切换。只需直接从 Dock 启动 Clicker for HBO Max 即可开始狂欢。 HBO Max 客户端 Clicker for HBO Max 下载 Clicker for HBO Max mac版安装教程 软件下载完成后&#xff0c;双击pkg根据提示进行安装 Clic…

27、Qt自定义标题栏

一、说明 QtWidget及其子类有默认的标题栏&#xff0c;但是这个标题栏不能美化&#xff0c;有时候满足不了我们的使用需求&#xff0c;所以进行自定义标题栏 二、下载图标 在下面的链接中下载两种颜色的最大化、向下还原、最大化和关闭八个图片&#xff0c;并找一张当做图标…

c++opencv Project3 - License Plate Detector

俄罗斯车牌识别案例&#xff1a;实时识别车牌&#xff0c;并且读取到指定文件夹中。 惯例先展示结果图&#xff1a; 对于摄像头读取图片进行车牌匹配&#xff0c;原理和人脸识别其实是一致的。 利用训练好的模型进行匹配即可。可参考&#xff1a; 对视频实现人脸识别-CSDN博…

MySQL索引(聚簇索引、非聚簇索引)

了解MySQL索引详细&#xff0c;本文只做整理归纳&#xff1a;https://blog.csdn.net/wangfeijiu/article/details/113409719 概念 索引是对数据库表中一列或多列的值进行排序的一种结构&#xff0c;使用索引可快速访问数据库表中的特定信息。 索引分类 主键索引&#xff1a…

drawio 网页版二次开发(1):源码下载和环境搭建

目录 一 说明 二 源码地址以及下载 三 开发环境搭建 1. 前端工程地址 2. 配置开发环境 &#xff08;1&#xff09;安装 node.js &#xff08;2&#xff09;安装 serve 服务器 3. 运行 四 最后 一 说明 应公司项目要求&#xff0c;需要对drawio进行二次开发&…

Redis学习1——redis简介、基础

介绍 redis简介 Redis(Remote Dictonary Server) 是由Salvatore Sanfilippo开发的key-value缓存数据库&#xff0c;基于C语言开发。目前市面上&#xff0c;Redis和MongoDB是当前使用最广泛的NoSQL&#xff0c;而就Redis技术而言&#xff0c;它的性能十分优越&#xff0c;可以…

HackMyVM-Animetronic

目录 信息收集 arp nmap nikto whatweb WEB web信息收集 feroxbuster steghide exiftool hydra ssh连接 提权 系统信息收集 socat提权 信息收集 arp ┌──(root㉿0x00)-[~/HackMyVM] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 08:00:27:9d:6d:7…

jenkins部署想定报错

报错&#xff1a; 解决办法&#xff1a; 登录被编译的设备&#xff0c;清楚旧代码&#xff0c;在重新执行

burp靶场xss漏洞(初级篇)

靶场地址 http://portswigger.net/web-security/all-labs#cross-site-scripting 第一关&#xff1a;反射型 1.发现搜索框直接注入payload <script>alert(111)</script> ​ 2.出现弹窗即说明攻击成功 ​ 第二关&#xff1a;存储型 1.需要在评论里插入payload …

object

object.clone() 在 Java 中&#xff0c;Object.clone() 方法执行的是浅拷贝&#xff08;shallow copy&#xff09;&#xff0c;而不是深拷贝&#xff08;deep copy&#xff09;。 浅拷贝&#xff08;Shallow Copy&#xff09;&#xff1a; 浅拷贝是指在拷贝对象时&#xff0…

Al Agent:开启智能化未来的关键角色,让机器更智能的为我们服务

文章目录 &#x1f680;Al Agent是什么&#x1f4d5;Al Agent的工作原理与技术&#x1f4aa;Al Agent应用领域&#x1f680;智能家居应用&#x1f308;医疗健康领域⭐金融服务行业&#x1f302;交通运输管理&#x1f3ac;教育培训应用 &#x1f512;Al Agent优势与挑战✊Al Age…

中国地形可调节高度-UE5-UE4

2000坐标系&#xff0c;可进行高度调整。 支持版本4.21-5.4版本 下载位置&#xff1a;https://mbd.pub/o/bread/ZpWZm5Zs

初探 JUC 并发编程:读写锁 ReentrantReadWriteLock 原理(8000 字源码详解)

本文中会涉及到一些前面 ReentrantLock 中学到的内容&#xff0c;先去阅读一下我关于独占锁 ReentrantLock 的源码解析阅读起来会更加清晰。 初探 JUC 并发编程&#xff1a;独占锁 ReentrantLock 底层源码解析 6.4&#xff09;读写锁 ReentrantReadWriteLock 原理 前面提到的 R…

LeetCode 209 长度最小的子数组(滑动窗口and暴力)

、 法一&#xff1a;滑动窗口 //使用滑动窗口来解决问题 //滑动窗口的核心点有&#xff1a; /*1.窗口内是什么&#xff1f;2.如何移动窗口的起始位置&#xff1f;3.如何移动窗口的结束位置&#xff1f;4.两个指针&#xff0c;怎么判断哪个指针是终止指针&#xff0c;哪个指针…

【核武器】2024 年美国核武器-20240507

2024年5月7日,《原子科学家公报》发布了最新版的2024美国核武器手册 Hans M. Kristensen, Matt Korda, Eliana Johns, and Mackenzie Knight, United States nuclear weapons, 2024, Bulletin of the Atomic Scientists, 80:3, 182-208, DOI: https://doi.org/10.1080/00963…

【JavaScript】内置对象 - 数组对象 ① ( 数组简介 | 数组创建 | 数组类型检测 )

文章目录 一、数组对象1、数组简介2、数组创建3、数组检测 - Array.isArray() 方法4、数组检测 - instanceof 运算符 Array 数组对象参考文档 : https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array 一、数组对象 1、数组简介 在 JavaScr…

嫁接打印的技术要点

所谓嫁接打印&#xff0c;是一种增减材混合制造的方式。它将已成形的模具零件当作基座&#xff0c;在此基础上“生长”出打印的零件。其中基座通常采用传统加工方式制造&#xff0c;而打印部分则使用专用的金属粉末&#xff0c;通过 3D 打印技术成型。 嫁接打印之所以备受欢迎&…

PyTorch 图像篇

计算机视觉技术是一门包括计算机科学与工程、神经生理学、物理学、信号处理、认知科学、应用数学与统计等多学科的综合性科学技术&#xff0c; 是人工智能的一个重要分支&#xff0c; 目前在智能安防、自动驾驶汽车、医疗保健、生成制造等领域具有重要的应用价值。 计算机视觉…

Spring AOP(3)

目录 Spring AOP原理 代理模式 代理模式中的主要角色 静态代理 动态代理 总结:面试题 什么是AOP? Spring AOP实现的方式有哪些? Spring AOP实现原理 Spring使用的是哪种代理方式? JDK和CGLIB动态代理的区别? Spring AOP原理 代理模式 代理模式, 也叫委托模式. …

网络安全之交换基础

交换属于二层技术。路由器&#xff08;router&#xff09;是三层设备&#xff0c;可以基于IP地址转发&#xff0c;但需要路由表来记录。 交换机&#xff08;switch&#xff09;是二层设备&#xff0c;网桥&#xff08;switch&#xff09;也是二层设备&#xff0c;这两个都是基…