新闻详情

新闻详情

首页 / 资讯中心 / 详情

QPainter 绘制坐标轴,数据散点,连线,可拖动

发布时间:2026/9/5 15:05:28来源:尧图网络
QPainter 绘制坐标轴,数据散点,连线,可拖动
最开始使用 qchart 实现项目要求 qchart不知道怎么实现XY轴上面的箭头 囧后面 轴上面显示的单位 移动不到 箭头附近 而且数据点需要散点类也需要连线数据list也有标题数据多 一点管理太麻烦数据拖动弄的一团糟。整了几天 还有一些细节还是不知道怎么设置查来查去 都是一些基础的东西还是太菜了学无止境后面等不起 用qpainter 实现 需要的功能 类似 qchart这是demo主要代码数据list使用结构体struct paint_point_struct { bool is_paint_data_title; // 是否绘制数据标题 QString title; // 数据标题 QListQPointFdata_list; // 绘图数据 bool is_draw_line; // 是否将数据点用线连接 Qt::PenStyle ps; // 线类型 bool is_draw_point; // 数据点是否绘制为圆点 int point_marker_size; // 圆点大小 paint_point_struct() { is_paint_data_title true; // 默认绘制数据标题 title.clear(); is_draw_line true; // 默认数据点用线连接 data_list.clear(); ps Qt::SolidLine; // 默认是实线 //ps Qt::DotLine; // 默认是虚线 is_draw_point true; // 默认数据点绘制为圆点 point_marker_size 5; // 圆点大小默认为5 } };/* 绘制标题 */ void mychart::paint_title(QPainter *painter) { if(title_string.isEmpty()) { title_height 0; return; } ResetDefaultCoordinate(painter); painter-setFont(*title_font); int width this-width() / 2; // int height this-height(); QFontMetrics fm(*title_font); int axis_x_string_width fm.width(title_string); int axis_x_string_heigh fm.height(); // X轴字符的高度 int rect_y 0 5; title_height rect_y axis_x_string_heigh 5; if(coordinate_dir) { rect_y 0; title_height 0; } QRectF rect(width - axis_x_string_width / 2, rect_y, axis_x_string_width, axis_x_string_heigh); painter-drawText(rect,title_string); title_height rect_y axis_x_string_heigh 5; }/* 绘制数据点 */ void mychart::paint_points(QPainter *painter) // 绘制数据点 { for(int i 0;i paint_point_list.length();i) { if(coordinate_dir) SetMathCoordinate(painter); else ResetDefaultCoordinate(painter); // 左上角 QPointF point_end; for(int j 0;j paint_point_list.at(i).data_list.length();j) { QPointF point_at_list paint_point_list.at(i).data_list.at(j); QPointF point; point.setX(m_ptStartPos.x() (point_at_list.x() - axis_x_range.x()) * m_axisWidth / (axis_x_range.y() - axis_x_range.x())); point.setY(m_ptStartPos.y() (point_at_list.y() - axis_y_range.x()) * m_axisHeight / (axis_y_range.y() - axis_y_range.x())); if(paint_point_list.at(i).is_draw_point) painter-drawEllipse(point,paint_point_list.at(i).point_marker_size,paint_point_list.at(i).point_marker_size); if(paint_point_list.at(i).is_draw_line) // 数据点用线连接 { if(j ! 0) { QPen pen; pen.setStyle(paint_point_list.at(i).ps); painter-setPen(pen); painter-drawLine(point, point_end);// 绘制数据连接线折线 } point_end point; } } /* 绘制数据标题 */ if(paint_point_list.at(i).is_paint_data_title !paint_point_list.at(i).title.isEmpty()) { ResetDefaultCoordinate(painter); // 左上角 QFont font(SimSun, 16, 50); painter-setFont(font); /* 确定字符的长宽 */ QFontMetrics fm(font); int axis_x_string_width fm.width(paint_point_list.at(i).title); int axis_x_string_heigh fm.height(); // X轴字符的高度 int rect_x point_end.x() paint_point_list.at(i).point_marker_size 10; int rect_y (point_end.y() - axis_x_string_heigh / 2); if(coordinate_dir) rect_y this-height() - rect_y - axis_x_string_heigh; QRectF rect(rect_x, rect_y, axis_x_string_width, axis_x_string_heigh); painter-drawText(rect,paint_point_list.at(i).title); } } }坐标轴刻度可能是其他乱七八糟的字符/* 绘制刻度文本 */ void mychart::paint_coordinate_scale_text(QPainter *painter) { ResetDefaultCoordinate(painter); painter-setFont(*text_font); /* 确定字符的长宽 */ QFontMetrics fm(*text_font); int axis_x_string_width fm.width(0); int axis_x_string_heigh fm.height(); // X轴字符的高度 for(int i 0;i axis_y_count;i) { /* 确定Y轴上的字符最大宽度 */ QString y_string (y_scale_string_list.isEmpty())? QString::number((axis_y_range.y() - axis_y_range.x()) / (axis_y_count - 1) * i,f,2): y_scale_string_list.at(i); int string_width fm.width(y_string); axis_x_string_width (string_width axis_x_string_width)?string_width:axis_x_string_width; } QPoint axisStartPoint; // 刻度线坐标 int string_scale_base 0; // 第一个刻度文本结束点坐标根据刻度范围动态显示刻度文本防止文本全部叠在一起 /* 画X刻度文本标识 */ int count (!x_scale_list.isEmpty())?x_scale_list.length():axis_x_count; for(int i count - 1;i 0;i--) // 从最后一个刻度文本开始优先绘制最大刻度文本 { qreal x m_ptStartPos.x() m_axisWidth / (count - 1) * i; if(!x_scale_list.isEmpty()) x m_ptStartPos.x() (x_scale_list.at(i) - x_scale_list.at(0)) * m_axisWidth / (x_scale_list.last() - x_scale_list.at(0)); axisStartPoint.setX(x); axisStartPoint.setY(m_ptStartPos.y()); QString scale_str (x_scale_string_list.isEmpty())? QString::number((axis_x_range.y() - axis_x_range.x()) / (count - 1) * i,f,0): x_scale_string_list.at(i); axis_x_string_width fm.width(scale_str); axis_x_string_heigh fm.height(); // X轴字符的高度 int rect_y axisStartPoint.y() - scale_value - axis_x_string_heigh; if(coordinate_dir) rect_y this-height() - rect_y - axis_x_string_heigh; QRectF rect(axisStartPoint.x() - axis_x_string_width / 2, rect_y, axis_x_string_width, axis_x_string_heigh); if(scale_str.isEmpty())continue; if(i count - 1) // 从最后一个刻度文本开始 { string_scale_base axisStartPoint.x() - axis_x_string_width / 2; // 计算文本起点X坐标 } if((axisStartPoint.x() axis_x_string_width / 2 string_scale_base) (i count - 1)) { continue; // 文本重叠 } else { string_scale_base axisStartPoint.x() - axis_x_string_width / 2; } painter-drawText(rect,scale_str); } /* 画Y刻度文本标识 */ count (!y_scale_string_list.isEmpty())?y_scale_string_list.length():axis_y_count; for(int i count - 1;i 0;i--) { qreal y m_ptStartPos.y() m_axisHeight / (count - 1) * i; if(!y_scale_list.isEmpty()) y m_ptStartPos.y() (y_scale_list.at(i) - y_scale_list.at(0)) * m_axisHeight / (y_scale_list.last() - y_scale_list.at(0)); axisStartPoint.setX(m_ptStartPos.x()); axisStartPoint.setY(y); QString scale_str (y_scale_string_list.isEmpty())? QString::number((axis_y_range.y() - axis_y_range.x()) / (count - 1) * i,f,2): y_scale_string_list.at(i); axis_x_string_width fm.width(scale_str); axis_x_string_heigh fm.height(); // X轴字符的高度 int rect_y axisStartPoint.y() - axis_x_string_heigh / 2; if(coordinate_dir) rect_y this-height() - rect_y - axis_x_string_heigh; QRectF rect(axisStartPoint.x() - scale_value - axis_x_string_width, rect_y, axis_x_string_width, axis_x_string_heigh); if(scale_str.isEmpty())continue; if(i count - 1) // 从最后一个刻度文本开始,优先绘制最大刻度文本 { string_scale_base axisStartPoint.y() - axis_x_string_heigh / 2; // 计算文本起点X坐标 } if((axisStartPoint.y() axis_x_string_heigh / 2 string_scale_base) (i count - 1)) { continue; // 文本重叠 } else { string_scale_base axisStartPoint.y() - axis_x_string_heigh / 2; } painter-drawText(rect,scale_str); } /* 设置XY轴单位字符 */ if(!x_unit_string.isEmpty()) { axis_x_string_width fm.width(x_unit_string); axis_x_string_heigh fm.height(); // X轴字符的高度 int rect_y m_ptStartPos.y() m_ptStartPos.x() / 10; if(coordinate_dir) rect_y this-height() - rect_y - axis_x_string_heigh; QRectF rect(m_ptStartPos.x() m_axisWidth m_ptStartPos.x() / 2 - axis_x_string_width / 2, rect_y, axis_x_string_width, axis_x_string_heigh); painter-drawText(rect,x_unit_string); } if(!y_unit_string.isEmpty()) { axis_x_string_width fm.width(y_unit_string); axis_x_string_heigh fm.height(); // Y轴字符的高度 int rect_y (m_ptStartPos.y() m_axisHeight m_ptStartPos.y() - axis_x_string_heigh); if(coordinate_dir) rect_y this-height() - rect_y - axis_x_string_heigh; QRectF rect(m_ptStartPos.x() m_axisHeight / 75 * 2, rect_y, axis_x_string_width, axis_x_string_heigh); painter-drawText(rect,y_unit_string); } }https://download.csdn.net/download/zsj_rainsy/87032911
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Astro 示例模板库实战指南:从 examples 目录到 create-astro 的底层实现 2026/9/5 15:35:32

Astro 示例模板库实战指南:从 examples 目录到 create-astro 的底层实现

Astro 示例模板库实战指南:从 examples 目录到 create-astro 的底层实现 【免费下载链接】astro The web framework for content-driven websites. ⭐️ Star to support our work! 项目地址: https://gitcode.com/GitHub_Trending/as/astro 本文以 Astro 官…

阅读更多 →
IOPaint 快速上手:一键安装 AI 图像修复工具,3分钟装好跑通第一张图 2026/9/5 15:35:32

IOPaint 快速上手:一键安装 AI 图像修复工具,3分钟装好跑通第一张图

IOPaint 快速上手:一键安装 AI 图像修复工具,3分钟装好跑通第一张图 【免费下载链接】IOPaint Image inpainting tool powered by SOTA AI Model. Remove any unwanted object, defect, people from your pictures or erase and replace(powered by stab…

阅读更多 →
射频工程师从零到一:ADS、Cadence与PCB设计实战路径 2026/9/5 15:35:32

射频工程师从零到一:ADS、Cadence与PCB设计实战路径

射频工程师这个岗位,听起来门槛很高,既要懂理论又要会仿真,还得能画板子。很多想入行或者刚入行的朋友,面对ADS、Cadence、PCB设计这一大堆工具和概念,往往不知道从哪里下手,更别提独立完成一个射频前端模块…

阅读更多 →
Hugo 有序分类法(Ordered Taxonomy)元素方法详解:Count、Page、Pages、Term 与 WeightedPages 2026/9/5 15:35:32

Hugo 有序分类法(Ordered Taxonomy)元素方法详解:Count、Page、Pages、Term 与 WeightedPages

Hugo 有序分类法(Ordered Taxonomy)元素方法详解:Count、Page、Pages、Term 与 WeightedPages 【免费下载链接】hugo The world’s fastest framework for building websites. 项目地址: https://gitcode.com/gh_mirrors/hu/hugo Hugo…

阅读更多 →
快速上手 superfile:终端文件管理器 5 分钟实战 2026/9/5 15:35:32

快速上手 superfile:终端文件管理器 5 分钟实战

快速上手 superfile:终端文件管理器 5 分钟实战 【免费下载链接】superfile Pretty fancy and modern terminal file manager 项目地址: https://gitcode.com/GitHub_Trending/su/superfile 整理下载目录是件烦心事:安装包、压缩包、临时文件堆在…

阅读更多 →
ICM20948九轴传感器实战:从SPI驱动到姿态解算全流程解析 2026/9/5 15:32:31

ICM20948九轴传感器实战:从SPI驱动到姿态解算全流程解析

简介:本资源是一套面向嵌入式开发者与物联网应用工程师的ICM20948九轴传感器驱动开发实践包,聚焦陀螺仪、加速度计与磁力计三合一运动感知模块的底层驱动实现与跨接口适配问题。压缩包共9个文件(26KB),含6个C源文件&am…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞