QPaint绘制自定义坐标轴组件00

最终效果

1.创建一个ui页面,修改背景颜色

鼠标右键->改变样式表->添加颜色->background-color->选择合适的颜色->ok->Apply->ok

重新运行就可以看到widget的背景颜色已经改好

2.创建一个自定义的widget窗口小部件类,class MyChart : public QWidget

mychart.h

#ifndef MYCHART_H
#define MYCHART_H#include <QWidget>
#include <QPainter>
#include <QString>struct DataNode
{int value;QString key;
};// MyChart继承自QWidget类,是一个窗口小部件。
class MyChart : public QWidget
{Q_OBJECT
public:// `explicit` 是 C++ 中的一个关键字,用于修饰类的构造函数,表示该构造函数只能用于显式地创建对象,不能被隐式地调用。// 只能通过MyChart painter = MyChart(parent)的方式显式地创建一个 `MyChart` 对象:// `parent` 参数的默认值为 `nullptr`,这表示如果没有提供父部件的指针,那么 `MyChart` 就没有父部件,即它是一个独立的窗口部件。explicit MyChart(QWidget *parent = nullptr);void updateValue(const DataNode &node);protected:// `paintEvent(QPaintEvent *event)` 是一个事件处理函数,// 在 Qt 框架中,当需要重绘窗口部件时就会自动触发 `paintEvent(QPaintEvent *event)` 函数,// 以便开发者可以实现窗口部件的绘制逻辑,从而更新窗口的显示内容。// 在窗口需要进行重绘时,Qt 框架会自动调用 `MyChart` 对象的 `paintEvent(QPaintEvent *event)` 函数,从而实现图表的绘制更新。// 由于 `paintEvent` 函数是在需要重绘窗口部件时自动调用的,因此我们不需要手动调用它。// 当然,如果需要手动更新窗口部件的显示内容,// 也可以使用 `QWidget` 类中提供的 `update()` 函数或 `repaint()` 函数来触发 `paintEvent` 函数的调用,// 从而实现窗口的重绘。但通常情况下,Qt 框架会自动处理窗口部件的刷新和重绘。// `paintEvent` 函数是在 `QWidget` 类中定义的虚函数,// 它被设计为在窗口部件需要重新绘制时自动调用,以便让程序员有机会对窗口的内容进行绘制修改。// 在 `QWidget` 子类中,如果需要修改默认的绘制行为,则可以重写 `paintEvent` 函数来实现。void paintEvent(QPaintEvent *event);private:int yMaxValue = 10;int maxNodeNum = 110;QList<DataNode> listDataNode;
};#endif // MYCHART_H

 mychart.cpp

#include "mychart.h"MyChart::MyChart(QWidget *parent) : QWidget(parent)
{}// 数据刷新
void MyChart::updateValue(const DataNode &node)
{// 如果当前列表中的数据节点数量已经达到了最大值 `maxNodeNum`,// 先删除队列头部的元素,即最早加入的元素(使用 `removeFirst()` 函数)。if(listDataNode.size() >= maxNodeNum) {listDataNode.removeFirst();}// 然后,将数据节点 `node` 添加到当前列表的末尾,使用 `append()` 函数实现。listDataNode.append(node);// 最后,将整个图表更新,调用 `update()` 函数。// `update()` 函数是用来触发 `paintEvent()` 函数的信号的。// 当窗口或控件需要更新或重绘自己时,它们会同时发射一个 `update()` 信号。// 这个信号会被 Qt 的事件循环机制捕获,最终调用 `paintEvent()` 函数进行绘图。// 因此,如果不调用 `update()` 函数,`paintEvent()` 函数就不会被调用,也就不会更新图表的显示内容。update();
}// 图标绘制
// `paintEvent` 函数中的调用实际上是在继承关系中向上查找到的 `QWidget::paintEvent()` 函数的实现,
// 它在需要绘制更新时被自动触发。
// 在默认情况下,这个函数为空实现,因此需要我们手动重写它并自己实现绘图功能。
void MyChart::paintEvent(QPaintEvent *event)
{(void)event;// `QPainter` 是 Qt 中的一个绘图工具类,它封装了各种绘制函数和处理设备上下文的能力。// 通过使用 `QPainter` 类可以在窗口、部件和其它设备上上进行绘图操作。// 通过调用 `painter` 的各种绘制函数可以在空白的窗口部件上一步步画出你需要的复杂图形,包括直线、圆弧、多边形、文本等等。// `this` 关键字是指向当前对象的指针,即指向调用成员函数的对象的指针。// `this` 关键字可以用来访问对象的成员变量和成员函数,区分局部变量和成员变量。// `this` 指的是当前 `MyChart` 类型的对象,也就是指示当前需要绘制图表的部件对象。// 在这个函数中,我们通过将对象指针传给 `QPainter` 构造函数,来创建一个绘制器,使用它进行绘图操作。// 需要注意的是,`this` 关键字指向的是对象的指针,而不是类本身。// 所以说,`this` 不是用来区分类和对象的关键字,而是用来访问对象内部成员的工具。QPainter painter(this);// 启用抗锯齿功能,即让绘制的线条、边缘等对锯齿进行平滑处理,让图像更加平滑和自然。painter.setRenderHint(QPainter::Antialiasing);// `QPen` 是 Qt 中的一个画笔类,用于控制绘图时线条的样式、颜色和粗细等参数,通常与 `QPainter` 类一起使用。// 在默认情况下,`QPen` 对象的颜色为黑色,线宽为0,样式为实线。// 可以通过 `setBrush()`、`setColor()`、`setWidth()`、`setStyle()` 等函数来设置画笔的各个属性。QPen pen;pen.setWidth(2);pen.setColor(QColor(100, 200, 100));// setPen(pen)将创建的 `QPen` 画笔对象传入painter,就可以使用该笔刷来绘制线条、形状、文本等各种图形元素了。painter.setPen(pen);//坐标轴// 高度int yLength = this->height() * 0.9;// 长度int xLength = this->width();// `QPoint` 类是 Qt 中的一个点类,用于表示二维平面坐标系中的一个点,其具体坐标值由 `x()` 和 `y()` 成员函数获取。// `zero` 是一个 `QPoint` 类型的点,由横坐标`this->width() * 0.03`纵坐标`this->height() * 0.95` 两个数值组成,// 它代表了坐标系中的原点或者起始点,用来确定坐标轴的位置。QPoint zero(this->width() * 0.03, this->height() * 0.95);// 以下两行代码通常表示绘制一个基础的坐标系,绘制坐标系通常是绘制图表的第一步,是各种图表展示中的基础步骤之一。// 从 `zero` 点开始,向上绘制一条长度为 `yLength` 的水平线段表示y轴,并向右绘制一条长度为 `xLength` 的垂直线段表示x轴。// 这里使用了 `QPoint` 类型的构造函数创建起始点和结束点的对象。// y轴,原点zero,终点QPoint(zero.x() + xLength, zero.y())painter.drawLine(zero, QPoint(zero.x(), zero.y() - yLength));// x轴,原点zero,终点QPoint(zero.x() + xLength, zero.y())painter.drawLine(zero, QPoint(zero.x() + xLength, zero.y()));// 刻度间隔数int durationX = 100;int durationY = 10;// 每个刻度之间间隔的长度int xPeriod = xLength / durationX - 1;int yPeriod = yLength / durationY - 1;// 绘制坐标轴上的刻度和数字,用以标示坐标轴上每个刻度对应的数值// 遍历 y 轴的每个刻度位置,从起点 `zero` 开始向上连续绘制 `durationY` 个横向线段用于表示刻度。for (int i = 0; i <= durationY; ++i) {// 绘制表示y轴刻度的水平线段painter.drawLine(QPoint(zero.x() - 1, zero.y() - i * yPeriod), QPoint(zero.x() + 5, zero.y() - i * yPeriod));QString value = QString::number(i * 2);// 绘制刻度数值painter.drawText(QPoint(zero.x() - 25, zero.y() - i * yPeriod + 5), value);}for (int i = 0; i < durationX; ++i) {// 绘制表示x轴刻度的垂直线段painter.drawLine(QPoint(zero.x() + i * xPeriod, zero.y() + 3), QPoint(zero.x() + i * xPeriod, zero.y() - 5));}// 更新数据QList<QPoint> pointList;for(int i = 0; i < listDataNode.size(); i++) {DataNode node = listDataNode.at(i);QString key = node.key;int value = node.value;// 当前数据在x轴位置对应的刻度值int xOffset = zero.x() + i * xPeriod;// 当前数据在y轴位置对应的刻度值int yOffset = value * yLength / yMaxValue;// 像数据列表中添加数据转换后对应的坐标点pointList << QPoint(xOffset, zero.y() - yOffset);// 使用 `QTransform` 类对绘制坐标文本的位置和方向进行变换QTransform transform;// `translate()` 函数将文本的绘制起点平移 (`xOffset + 5`, `zero.y() - 7`) 的位置,// 即向右偏移5个像素,向上偏移7个像素,这是调试后比较合适的显示位置transform.translate(xOffset + 5, zero.y() - 7);// `rotate(-45)` 函数将文本沿顺时针方向旋转 45 度。transform.rotate(-45);// `setTransform()` 函数将 transform 对象设置为画笔对象 painter 的当前变换矩阵。painter.setTransform(transform);// `drawText()` 函数在变换后的位置绘制文本。painter.drawText(0, 5, key);// `resetTransform()` 函数将画笔对象的变换矩阵重置为原始状态。// 这个步骤很重要,如果不重置的话,下次绘制的文本会沿之前的变换矩阵进行绘制。painter.resetTransform();}// 折线线条宽度pen.setWidth(3);// 折现线条颜色pen.setColor(Qt::red);painter.setPen(pen);// 遍历并连接个数据节点,绘制折线for(int i = 0; i < pointList.size(); i++) {if((i+1) < pointList.size()) {// 连接个数据点,绘制折线painter.drawLine(pointList.at(i), pointList.at(i+1));}}
}

3.添加一个用于绘制自定义控件的控件,一般是Qwidget,修改QWidget的类属性,提升为自定义的类

提升类完成后qt designer显示当前组件已经是MyChart类

 重新编译运行后,原来的QWidget子窗口页面变成了自定义的Mychart页面

编写应用代码,应用自己编写的MyChart类实现数据刷新

charttest.h

#ifndef CHARTTEST_H
#define CHARTTEST_H#include <QWidget>
#include <QTimer>
#include <QTime>
#include "mychart.h"QT_BEGIN_NAMESPACE
namespace Ui { class ChartTest; }
QT_END_NAMESPACEclass ChartTest : public QWidget
{Q_OBJECTpublic:ChartTest(QWidget *parent = nullptr);~ChartTest();void initState();private:Ui::ChartTest *ui;int index = 0;QTimer timer;   //定时器
};
#endif // CHARTTEST_H

charttest.cpp 

#include "charttest.h"
#include "ui_charttest.h"ChartTest::ChartTest(QWidget *parent): QWidget(parent), ui(new Ui::ChartTest)
{ui->setupUi(this);initState();
}ChartTest::~ChartTest()
{timer.stop();delete ui;
}void ChartTest::initState()
{this->resize(1000, 400);connect(&timer, &QTimer::timeout, [=](){// 模拟数据static int y = 1;if (y++ >= 9) {y = 1;}static int value = 0;DataNode node = {y, "ABC" + QString::number(value++)};// 刷新数据ui->widget->updateValue(node);});timer.start(50);
}

main.cpp 

#include "charttest.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);ChartTest w;w.show();return a.exec();
}

ChartTest.pro 

QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \charttest.cpp \mychart.cppHEADERS += \charttest.h \mychart.hFORMS += \charttest.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

编写晚代码后运行效果

 

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

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

相关文章

个人 AI 的革命:Nvidia‘s Chat with RTX 深度探索

个人 AI 的革命&#xff1a;Nvidias Chat with RTX 深度探索 Nvidia 推出的 Chat with RTX 预示着个人 AI 新时代的到来。2 月 13 日&#xff0c;Nvidia 官宣了自家的 AI 聊天机器人&#xff0c;这不仅是人工智能交互的渐进式改进&#xff1b;更代表了个人如何利用自己的数据进…

MySQL 基础知识(八)之用户权限管理

目录 1 MySQL 权限管理概念 2 用户管理 2.1 创建用户 2.2 查看当前登录用户 2.3 修改用户名 2.4 删除用户 3 授予权限 3.1 授予用户管理员权限 3.2 授予用户数据库权限 3.3 授予用户表权限 3.4 授予用户列权限 4 查询权限 5 回收权限 1 MySQL 权限管理概念 关于 M…

用tensorflow模仿BP神经网络执行过程

文章目录 用矩阵运算仿真BP神经网络y relu ( (X․W ) b )y sigmoid ( (X․W ) b ) 以随机数产生Weight(W)与bais(b)placeholder 建立layer函数改进layer函数&#xff0c;使其能返回w和b github地址https://github.com/fz861062923/TensorFlow 用矩阵运算仿真BP神经网络 impo…

电源管理芯片是指在电子设备系统中,负责对电能的变换、分配、检测等进行管理的芯片

萨科微半导体宋仕强介绍说&#xff0c;电源管理芯片是指在电子设备系统中&#xff0c;负责对电能的变换、分配、检测等进行管理的芯片&#xff0c;其性能和可靠性直接影响电子设备的工作效率和使用寿命&#xff0c;是电子设备中的关键器件。萨科微slkor&#xff08;www.slkormi…

人工智能专题:基础设施行业智能化的基础设施,自智网络双价值分析

今天分享的是人工智能系列深度研究报告&#xff1a;《人工智能专题&#xff1a;基础设施行业智能化的基础设施&#xff0c;自智网络双价值分析》。 &#xff08;报告出品方&#xff1a;埃森哲&#xff09; 报告共计&#xff1a;32页 自智网络驱动的电信产业变革 经过多年的…

电商小程序08调用缓存

目录 1 将信息存入缓存中2 获取登录信息3 退出登录4 发布预览总结 小程序的登录功能里&#xff0c;如果只是将登录信息保存到全局变量中&#xff0c;存在的问题是如果小程序重新打开&#xff0c;用户的登录状态就丢失了。为了解决这个问题&#xff0c;我们需要用到微搭的缓存的…

云计算基础-快照与克隆

快照及克隆 什么是快照 快照是数据存储的某一时刻的状态记录&#xff0c;也就是把虚拟机当前的状态保存下来(快照不是备份&#xff0c;快照保存的是状态&#xff0c;备份保存的是副本) 快照优点 速度快&#xff0c;占用空间小 快照工作原理 在了解快照原理前&#xff0c;…

文生图提示词:天气条件

天气和气候 --天气条件 Weather Conditions 涵盖了从基本的天气类型到复杂的气象现象&#xff0c;为描述不同的天气和气候条件提供了丰富的词汇。 Sunny 晴朗 Cloudy 多云 Overcast 阴天 Partly Cloudy 局部多云 Clear 清晰 Foggy 雾 Misty 薄雾 Hazy 朦胧 Rainy 下雨 Showers …

【C++】实现Date类的各种运算符重载

上一篇文章只实现了operator操作符重载&#xff0c;由于运算符较多&#xff0c;该篇文章单独实现剩余所有的运算符重载。继续以Date类为例&#xff0c;实现运算符重载&#xff1a; 1.Date.h #pragma once#include <iostream> #include <assert.h>using namespace …

Leecode之面试题消失的数字

一.题目及剖析 https://leetcode.cn/problems/missing-number-lcci/description/ 方法有很多,这里将两种时间复杂度为O(N)的方法 二.思路引入 第一种方法 先将0-n的总和求出来,在求出数组的总和,在做差就能得到消失的数字,不过要注意的是数据有可能溢出,这个方法很简单就不再…

【MySQL】Java的JDBC编程

数据库编程 1. 数据库编程的必备条件2. Java的数据库编程&#xff1a;JDBC3. JDBC工作原理4. JDBC使用4.1 JDBC开发案例4.2 JDBC使用步骤总结 5. JDBC常用接口和类5.1 JDBC API5.2 数据库连接Connection5.3 Statement对象5.4 ResultSet对象 面试问答&#xff1a; 1. 数据库编程…

腾讯云幻兽帕鲁服务器配置怎么选择合适?

腾讯云幻兽帕鲁服务器配置怎么选&#xff1f;根据玩家数量选择CPU内存配置&#xff0c;4到8人选择4核16G、10到20人玩家选择8核32G、2到4人选择4核8G、32人选择16核64G配置&#xff0c;腾讯云百科txybk.com来详细说下腾讯云幻兽帕鲁专用服务器CPU内存带宽配置选择方法&#xff…

如何在CSS中实现背景图片的渐变?

--引言 在CSS中&#xff0c;实现背景图片的渐变通常需要使用linear-gradient或者radial-gradient函数&#xff0c;这些函数可以与背景图像一起使用来创建渐变效果。然而&#xff0c;CSS的渐变并不直接支持使用图像作为渐变的颜色停止点。但你可以通过一些技巧来实现类似的效果…

MySQL篇----第十九篇

系列文章目录 文章目录 系列文章目录前言一、什么是存储过程?用什么来调用?二、如何通俗地理解三个范式?三、什么是基本表?什么是视图?四、试述视图的优点?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这…

Linux项目自动化构建工具-make/Makefile

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 背景 理解 实例代码 依赖关系 依赖方法 原理 项目清理 总结 前言 世上有两种耀眼的光芒&#xff0c;一种是正在升起的太阳&#xff0c;一种是正在努力学习编程…

Ansible fetch 模块 该模块用于从远程某主机获取(复制)文件到本地

这里写目录标题 参数实例查看返回结果在这里插入图片描述 参数 dest&#xff1a;用来存放文件的目录 src&#xff1a;在远程拉取的文件&#xff0c;并且必须是一个file&#xff0c;不能是**目录* 实例 ansible slave -m fetch -a src/data/hello.txt dest/data/可以看到一个…

Chat with RTX 安装

1、Chat With RTX 介绍 Chat With RTX 是一个 Demo&#xff0c;用来将您自己的资料&#xff08;文档、笔记、视频或其他数据&#xff09;与大语言模型建立连接&#xff0c;从而令 LLM 更具个性化。利用检索增强生成 (RAG)、TensorRT-LLM 和 RTX 加速&#xff0c;您可以与自定义…

ChatGPT绘图指南:DALL.E3玩法大全(一)

一、 DALLE.3 模型介绍 1、什么是 DALLE.3 模型&#xff1f; DALLE-3模型&#xff0c;是一种由OpenAI研发的技术&#xff0c;它是一种先进的生成模型&#xff0c;可以将文字描述转化为清晰的图片。这种模型的名称"DALLE"实际上是"Deep Auto-regressive Latent …

让每次生成的随机数都相同np.random.seed()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 让每次生成的随机数都相同 np.random.seed() 选择题 关于以下代码输出的结果说法正确的是&#xff1f; import numpy as np np.random.seed(0) print(【执行】print(np.random.rand(3))) prin…

EXTI外部中断

&#xff1f; 难点&#xff1a;中断向量表、看门狗、NVIC的优先级位&#xff1f;EXTI框图&#xff1f; ------------------------ 中断系统 中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;--->例如&#xff1a;…