【1】实例代码

(1)代码目录结构(备注:QtCreator默认步骤新建工程)

(2)工程pro文件

 QT       += core gui

 greaterThan(QT_MAJOR_VERSION, ): QT += widgets

 TARGET = painter
TEMPLATE = app SOURCES += main.cpp\
mainwindow.cpp HEADERS += mainwindow.h FORMS += mainwindow.ui

(3)头文件

 #ifndef MAINWINDOW_H
#define MAINWINDOW_H #include <QtGui>
#include <QPaintEvent>
#include <QMainWindow> #include <ctime>
#include <cstdlib> namespace Ui
{
class MainWindow;
} class MainWindow : public QMainWindow
{
Q_OBJECT public:
explicit MainWindow(QWidget *parent = );
~MainWindow(); void Paint(); public slots:
void onRefresh();
protected:
void paintEvent(QPaintEvent *); private:
Ui::MainWindow *ui;
QImage m_image;
QPainter *m_painter;
}; #endif // MAINWINDOW_H

(4)实现文件

 #include "mainwindow.h"
#include "ui_mainwindow.h" #define POINTSNUM 10
#define LowerFactor 0.8
#define UpperFactor 1.2 typedef struct Data
{
double scaleRange;
double maxScale;
double minScale;
QVector<double> vecData; Data() : scaleRange(0.0), maxScale(0.0), minScale(0.0)
{}
void init()
{
for (int i = ; i < POINTSNUM; ++i)
{
if (i % )
vecData.append(rand() % - );
else
vecData.append(rand() % + );
}
double maxElement = *(std::max_element(vecData.begin(), vecData.end()));
double minElement = *(std::min_element(vecData.begin(), vecData.end()));
if (maxElement < )
{
maxScale = maxElement * LowerFactor;
minScale = minElement * UpperFactor;
}
else if ( == maxElement)
{
maxScale = ;
minScale = minElement * UpperFactor;
}
else if (maxElement > && minElement < )
{
maxScale = maxElement * UpperFactor;
minScale = minElement * UpperFactor;
}
else if (minElement > )
{
maxScale = maxElement * UpperFactor;
minScale = minElement * LowerFactor;
} scaleRange = maxScale - minScale;
}
void print()
{
for (int i = ; i < POINTSNUM; ++i)
{
qDebug () << i << "::" << vecData[i] << " ";
}
qDebug() << endl;
}
}DataInfo; MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->mainToolBar->setVisible(true); QAction *pAction = new QAction("refresh", this);
ui->mainToolBar->addAction(pAction);
connect(pAction, &QAction::triggered, this, &MainWindow::onRefresh); resize(, ); // 窗体大小 宽度1000 高度730 m_image = QImage(, , QImage::Format_RGB32); // 画布的初始化大小设为,使用32位颜色
QColor backColor = qRgb(, , ); // 画布初始化背景色使用白色
m_image.fill(backColor); // 对画布进行填充 m_painter = new QPainter(&m_image);
m_painter->setRenderHint(QPainter::Antialiasing, true); // 设置反锯齿模式 Paint();
} void MainWindow::onRefresh()
{
m_painter->fillRect(, , - , - , Qt::white);
Paint();
update();
} void MainWindow::Paint()
{
// 确定坐标轴起点坐标
int pointx = , pointy = ; // 确定坐标轴宽度和高度,上文已定义画布大小,宽高依此而定。
int width = - pointx - ; // 宽度 = 画布宽度 - 坐标起点x - 右端间隙
int height = - * ; // 高度 = 画布高度 - 上下端的间隙高度 // 绘制视图区域
// 即外围的矩形(由左上角与右下角的两个点确定一个矩形)
m_painter->drawRect(, , - , - ); // 绘制X、Y1、Y2轴
QPointF xStartPoint(pointx, pointy);
QPointF xEndPoint(width + pointx, pointy);
m_painter->drawLine(xStartPoint, xEndPoint); // 坐标轴x宽度为width QPointF y1StartPoint(pointx, pointy - height);
QPointF y1EndPoint(pointx, pointy);
m_painter->drawLine(y1StartPoint, y1EndPoint); // 坐标轴y1高度为height QPointF y2StartPoint(pointx + width, pointy - height);
QPointF y2EndPoint(pointx + width, pointy);
m_painter->drawLine(y2StartPoint, y2EndPoint); // 坐标轴y2高度为height // (2)获得数据并分析最大值与最小值
DataInfo vectorX, vectorY1, vectorY2; // 数据储存在容器中,大小为POINTSNUM]
// 模拟随机数据
srand((int)time(NULL));
vectorX.init();
vectorY1.init();
vectorY2.init(); vectorX.print();
vectorY1.print();
vectorY2.print(); double kx = (double)(width / vectorX.scaleRange); // x轴的系数
double ky1 = (double)(height / vectorY1.scaleRange); // y1方向的比例系数
double ky2 = (double)(height / vectorY2.scaleRange); // y2方向的比例系数 // (3)绘制点
QPen penPointY1, penPointY2;
penPointY1.setColor(Qt::blue);
penPointY1.setWidth(); penPointY2.setColor(Qt::red);
penPointY2.setWidth(); for (int i = ; i < POINTSNUM; ++i)
{
double dXStart = pointx + kx * (vectorX.vecData[i] - vectorX.minScale);
m_painter->setPen(penPointY1); // 蓝色的笔,用于标记Y1各个点
m_painter->drawPoint(dXStart, pointy - (vectorY1.vecData[i] - vectorY1.minScale) * ky1); m_painter->setPen(penPointY2); // 红色的笔,用于标记Y2各个点
m_painter->drawPoint(dXStart, pointy - (vectorY2.vecData[i] - vectorY2.minScale) * ky2);
} // (4) 绘制刻度线
QPen penDegree;
penDegree.setColor(Qt::black);
penDegree.setWidth();
m_painter->setPen(penDegree); // x轴刻度线和值
// x轴 第一个刻度值
m_painter->drawText(pointx + , pointy + , QString::number(vectorX.minScale, 'f', ));
for (int i = ; i < POINTSNUM - ; ++i) // 分成10份
{
// // 选取合适的坐标,绘制一段长度为4的直线,用于表示刻度
// m_painter->drawLine(pointx + (i + 1) * width/10, pointy,
// pointx + (i+1)*width/10, pointy + 4); m_painter->drawText(pointx + (i+0.9) * width / POINTSNUM, pointy + , // 值的位置信息
QString::number(vectorX.minScale + (i+) * (vectorX.scaleRange/POINTSNUM), 'f', ));
}
// x轴 最后一个刻度值
m_painter->drawText(pointx + (POINTSNUM - + 0.8) * width / POINTSNUM, pointy + ,
QString::number(vectorX.maxScale, 'f', )); xStartPoint.setX(pointx);
xStartPoint.setY(pointy + );
xEndPoint.setX(pointx + width);
xEndPoint.setY(pointy + );
m_painter->drawLine(xStartPoint, xEndPoint); m_painter->drawText(pointx + width/, pointy + , QString("X")); // y1轴刻度线和值
// y1轴 第一个刻度值
m_painter->drawText(pointx - , pointy - , QString::number(vectorY1.minScale, 'f', ));
for (int i = ; i < POINTSNUM - ; ++i)
{
// 代码较长,但是掌握基本原理即可。
// 主要就是确定一个位置,然后画一条短短的直线表示刻度。 // m_painter->drawLine(pointx, pointy-(i+1)*height/10,
// pointx-4, pointy-(i+1)*height/10); m_painter->drawText(pointx - , pointy - (i+0.85) * height/POINTSNUM,
QString::number(vectorY1.minScale + (i+) * (vectorY1.scaleRange/POINTSNUM), 'f', ));
}
// y1轴 最后一个刻度值
m_painter->drawText(pointx - , pointy - (POINTSNUM - + 0.85) * height/POINTSNUM,
QString::number(vectorY1.maxScale, 'f', )); y1StartPoint.setX(pointx - );
y1StartPoint.setY(pointy - height); y1EndPoint.setX(pointx - );
y1EndPoint.setY(pointy);
m_painter->drawLine(y1StartPoint, y1EndPoint); m_painter->drawText(pointx - , pointy - height/, QString("Y1")); // y2轴刻度线和值
// y2轴 第一个刻度值
m_painter->drawText(pointx + width + , pointy - , QString::number(vectorY2.minScale, 'f', ));
for (int i = ; i < POINTSNUM - ; ++i)
{
// m_painter->drawLine(pointx + width, pointy-(i+1)*height/10,
// pointx + width + 4, pointy-(i+1)*height/10); m_painter->drawText(pointx + width + , pointy - (i+0.85)*height/POINTSNUM,
QString::number((vectorY2.minScale + (i+)*(vectorY2.scaleRange/POINTSNUM)), 'f' , ));
}
// Y2轴 最后一个刻度值
m_painter->drawText(pointx + width + , pointy - (POINTSNUM - + 0.85)*height/POINTSNUM,
QString::number(vectorY2.maxScale, 'f', )); y2StartPoint.setX(pointx + width + );
y2StartPoint.setY(pointy - height); y2EndPoint.setX(pointx + width + );
y2EndPoint.setY(pointy);
m_painter->drawLine(y2StartPoint, y2EndPoint); m_painter->drawText(pointx + width + , pointy - height/, QString("Y2")); // (5)绘制网格
QPen penDotLine;
penDotLine.setStyle(Qt::DotLine);
m_painter->setPen(penDotLine);
for (int i = ; i < POINTSNUM; ++i)
{
// 垂直线
m_painter->drawLine(pointx + (i+)* width/POINTSNUM, pointy,
pointx + (i+)* width/POINTSNUM, pointy - height);
// 水平线
m_painter->drawLine(pointx, pointy-(i+)*height/POINTSNUM,
pointx + width, pointy-(i+)*height/POINTSNUM);
}
} MainWindow::~MainWindow()
{
delete ui;
delete m_painter;
} void MainWindow::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.drawImage(, , m_image);
}

(5)main文件

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

【2】效果图

运行结果图如下:

Good Good Study, Day Day Up.

顺序 选择 循环 总结

利用QPainter绘制散点图的更多相关文章

  1. PyQt5利用QPainter绘制各种图形

    这个例子我做了好几天: 1)官网C++的源码,改写成PyQt5版本的代码,好多细节不会转化 2)网上的PyQt的例子根本运行不了 填了无数个坑,结合二者,终于能完成了一个关于绘图的东西.这个过程也掌握 ...

  2. 利用QPainter绘制各种图形(Shape, Pen 宽带,颜色,风格,Cap,Join,刷子)

    利用QPainter绘制各种图形 Qt的二维图形引擎是基于QPainter类的.QPainter既可以绘制几何形状(点.线.矩形.椭圆.弧形.弦形.饼状图.多边形和贝塞尔曲线),也可以绘制像素映射.图 ...

  3. 【带着canvas去流浪(4)】绘制散点图

    目录 一. 任务说明 二. 重点提示 三. 示例代码 四.散点hover交互效果的实现 4.1 基本算法 4.2 参考代码 4.3 Demo中的小问题 示例代码托管在:http://www.githu ...

  4. 带着canvas去流浪系列之四 绘制散点图

    [摘要] 用原生canvasAPI实现百度Echarts图表 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI ...

  5. C#利用GDI+绘制旋转文字等效果

    C#中利用GDI+绘制旋转文本的文字,网上有很多资料,基本都使用矩阵旋转的方式实现.但基本都只提及按点旋转,若要实现在矩形范围内旋转文本,资料较少.经过琢磨,可以将矩形内旋转转化为按点旋转,不过需要经 ...

  6. 利用PowerDesigner绘制PDM生成SQL Server数据库

    PowerDesigner是个很强大的建模工具,可以利用它绘制各种图形,本文利用该工具绘制PDM,进而生成SQL Server数据库. 比如绘制一个简单的学生选课.教师授课管理系统的PDM: pk表示 ...

  7. 在OpenCV中利用鼠标绘制矩形和截取图像的矩形区域

    这是两个相关的程序,前者是后者的基础.实际上前一个程序也是在前面博文的基础上做的修改,请参考<在OpenCV中利用鼠标绘制直线> .下面贴出代码. 程序之一,在OpenCV中利用鼠标绘制矩 ...

  8. 利用JFreeChart绘制股票K线图完整解决方案

    http://blog.sina.com.cn/s/blog_4ad042e50100q7d9.html 利用JFreeChart绘制股票K线图完整解决方案 (2011-04-30 13:27:17) ...

  9. Python使用Plotly绘图工具,绘制散点图、线形图

    今天在研究Plotly绘制散点图的方法 使用Python3.6 + Plotly Plotly版本2.0.0 在开始之前先说说,还需要安装库Numpy,安装方法在我的另一篇博客中有写到:https:/ ...

随机推荐

  1. 【python基础】sys

    sys模块 参考: https://blog.csdn.net/qq_38526635/article/details/81739321 http://www.cnblogs.com/cherishr ...

  2. es6 学习四 数组的学习

    1. Array.from() 语法: Array.from(arrayLike[, mapFn[, thisArg]]) arrayLike 类数组对象 mapFn 如果指定了该参数,新数组中的每个 ...

  3. 谈谈javascript数组排序方法sort()的使用,重点介绍参数使用及内部机制?

    语法:arrayObject.sort(sortby) 参数sortby可选,规定排序顺序,必须是函数: 注:如果调用该方法时没有使用参数,将按字符编码的顺序进行排序,要实现这一点,首先应把数组的元素 ...

  4. tomcat 的acceptCount、acceptorThreadCount、maxConnections、maxThreads 如何确定

    acceptCount 连接在被ServerSocketChannel accept之前就暂存在这个队列中,acceptCount就是这个队列的最大长度. ServerSocketChannel ac ...

  5. python练习题-day2

    1.判断下列逻辑语句的True,False 1)1 > 1 or 3 < 4 or 4 > 5 and 2 > 1 and 9 > 8 or 7 < 6 True ...

  6. MySQL crash-safe replication【转载】

    本文来自david大神的博客,innodb技术内幕的作者. http://insidemysql.blog.163.com/blog/static/202834042201385190333/ MyS ...

  7. 前端开发---HTML---介绍

    阅读目录 1.标签 2.HTML目录结构 3.HTML注释 一.web1.0时代的网页制作 静态网页,所谓的静态网页就是没有与用户进行交互而仅仅供读者浏览的网页,我们当时称为“牛皮癣”网页.例如一篇Q ...

  8. JetBrains 2017/2018全系列产品激活工具

    可谓是工欲善其事,必先利其器,相信作为优秀开发工程师的你都想拥有一套快捷高效的编码工具,而JetBrains这家公司的产品,不管是那种编程语言,其开发工具确实让开发者们着迷,JetBrains的产品博 ...

  9. Windows平台Mysql表名变小写的解决过程

    由于要弄某个项目的数据库设计文档,几百张表,如果弄在word文档里面一个个添加,效率比较低. 故分别使用了Mysql WorkBench(win版)和Powerdesigner 15来做这个设计文档. ...

  10. 【4】axios 获取数据

    API:https://www.kancloud.cn/yunye/axios/234845 基于axios进行二次封装 安装axios npm install axios --save 安装成功 [ ...