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
编写晚代码后运行效果
相关文章:

QPaint绘制自定义坐标轴组件00
最终效果 1.创建一个ui页面,修改背景颜色 鼠标右键->改变样式表->添加颜色->background-color->选择合适的颜色->ok->Apply->ok 重新运行就可以看到widget的背景颜色已经改好 2.创建一个自定义的widget窗口小部件类,class MyChart…...

MATLAB|基于改进二进制粒子群算法的含需求响应机组组合问题研究(含文献和源码)
目录 主要内容 模型研究 1.改进二进制粒子群算法(BPSO) 2.模型分析 结果一览 下载链接 主要内容 该程序复现《A Modified Binary PSO to solve the Thermal Unit Commitment Problem》,主要做的是一个考虑需求响应的机组组合…...

JDBC核心技术
第1章 JDBC概述 第2章 获取数据库连接 第3章 使用PreparedStatement实现CRUD操作 第4章 操作BLOB类型字段 第5章 批量插入 第6章 数据库事务 第7章 DAO及相关实现类 第8章 数据库连接池 第9章 Apache-DBUtils实现CRUD操作图像 小部件...
【天幕系列 02】开源力量:揭示开源软件如何成为技术演进与社会发展的引擎
文章目录 导言01 开源软件如何推动技术创新1.1 开放的创新模式1.2 快速迭代和反馈循环1.3 共享知识和资源1.4 生态系统的建设和扩展1.5 开放标准和互操作性 02 开源软件的商业模式2.1 支持和服务模式2.2 基于订阅的模式2.3 专有附加组件模式2.4 开源软件作为平台模式2.5 双重许…...

“挖矿”系列:细说Python、conda 和 pip 之间的关系
继续挖矿,挖“金矿”! 1. Python、conda 和 pip(挖“金矿”工具) Python、conda 和 pip 是在现代数据科学和软件开发中常用的工具,它们各自有不同的作用,但相互之间存在密切的关系: Python&…...

【自然语言处理】实验3,文本情感分析
清华大学驭风计划课程链接 学堂在线 - 精品在线课程学习平台 (xuetangx.com) 代码和报告均为本人自己实现(实验满分),只展示主要任务实验结果,如果需要详细的实验报告或者代码可以私聊博主 有任何疑问或者问题,也欢…...

2.12日学习打卡----初学RocketMQ(三)
2.12日学习打卡 目录: 2.12日学习打卡一. RocketMQ高级特性(续)消息重试延迟消息消息查询 二.RocketMQ应用实战生产端发送同步消息发送异步消息单向发送消息顺序发送消息消费顺序消息全局顺序消息延迟消息事务消息消息查询 一. RocketMQ高级特…...

<网络安全>《35 网络攻防专业课<第一课 - 网络攻防准备>》
1 主要内容 认识黑客 认识端口 常见术语与命令 网络攻击流程 VMWare虚拟环境靶机搭建 2 认识黑客 2.1 白帽、灰帽和黑帽黑客 白帽黑客是指有能力破坏电脑安全但不具恶意目的黑客。 灰帽黑客是指对于伦理和法律态度不明的黑客。 黑帽黑客经常用于区别于一般(正面…...

【实战】一、Jest 前端自动化测试框架基础入门(一) —— 前端要学的测试课 从Jest入门到TDD BDD双实战(一)
文章目录 一、前端要学的测试课1.前端要学的测试2.前端工程化的一部分3.前端自动化测试的例子4.前端为什么需要自动化测试?5.课程涵盖内容6.前置技能7.学习收获 二、Jest 前端自动化测试框架基础入门1. 自动化测试背景及原理前端自动化测试产生的背景及原理 2.前端自…...

蓝桥杯Java组备赛(二)
题目1 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();int max Integer.MIN_VALUE;int min Integer.MAX_VALUE;double sum 0;for(int i0;i<n;i) {int x sc.nextInt()…...

人力资源智能化管理项目(day10:首页开发以及上线部署)
学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/humanResourceIntelligentManagementProject 首页-基本结构和数字滚动 安装插件 npm i vue-count-to <template><div class"dashboard"><div class"container"><!-- 左侧内…...

Conda管理Python不同版本教程
Conda管理Python不同版本教程 目录 0.前提 1.conda常用命令 2.conda设置国内源(以添加清华源为例,阿里云源同样) 3.conda管理python库 4.其它 不太推荐 pyenv管理Python不同版本教程(本人另一篇博客,姊妹篇&…...

free pascal:fpwebview 组件通过 JSBridge 调用本机TTS
从 https://github.com/PierceNg/fpwebview 下载 fpwebview-master.zip 简单易用。 先请看 \fpwebview-master\README.md cd \lazarus\projects\fpwebview-master\demo\js_bidir 学习 js_bidir.lpr ,编写 js_bind_speak.lpr 如下,通过 JSBridge 调用本…...

数据结构——单链表专题
目录 1. 链表的概念及结构2. 实现单链表初始化尾插头插尾删头删查找在指定位置之前插入数据在指定位置之后插入数据删除指定位之前的节点删除指定位置之后pos节点销毁链表 3. 完整代码test.cSList.h 4. 链表的分类 1. 链表的概念及结构 在顺序表中存在一定的问题: …...

Linux:开源世界的王者
在科技世界中,Linux犹如一位低调的王者,统治着开源世界的半壁江山。对于许多技术爱好者、系统管理员和开发者来说,Linux不仅仅是一个操作系统,更是一种信仰、一种哲学。 一、开源的魅力 Linux的最大魅力在于其开源性质。与封闭的…...

⭐北邮复试刷题103. 二叉树的锯齿形层序遍历 (力扣每日一题)
103. 二叉树的锯齿形层序遍历 给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。 示例 1:输入:…...

文件上传漏洞--Upload-labs--Pass07--点绕过
一、什么是点绕过 在Windows系统中,Windows特性会将文件后缀名后多余的点自动删除,在网页源码中,通常使用 deldot()函数 对点进行去除,若发现网页源代码中没有 deldot() 函数,则可能存在 点绕过漏洞。通过点绕过漏洞&…...
MySQL高级特性篇(1)-JSON数据类型的应用
MySQL是一种常用的关系型数据库管理系统,它提供了多种数据类型,其中包括JSON数据类型。JSON(JavaScript Object Notation)是一种常用的数据交换格式,它以键值对的形式组织数据,并支持嵌套和数组结构。MySQL…...

如何用Qt实现一个无标题栏、半透明、置顶(悬浮)的窗口
在Qt框架中,要实现一个无标题栏、半透明、置顶(悬浮)的窗口,需要一些特定的设置和技巧。废话不多说,下面我将以DrawClient软件为例,介绍一下实现这种效果的四个要点。 要点一:移除标题栏&#…...

ViT: transformer在图像领域的应用
文章目录 1. 概要2. 方法3. 实验3.1 Compare with SOTA3.2 PRE-TRAINING DATA REQUIREMENTS3.3 SCALING STUDY3.4 自监督学习 4. 总结参考 论文: An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 代码:https://github.com…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...