【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. IAM:亚马逊访问权限控制

    IAM的策略.用户->服务器(仓库.业务体) IAM:亚马逊访问权限控制(AWS Identity and Access Management )IAM使您能够安全地控制用户对 AWS 服务和资 ...

  2. windows(64位)下使用curl安装

    windows(64位)下使用curl安装 转自:https://blog.csdn.net/wkj001/article/details/54889907 2017年02月06日 09:46:47  ...

  3. 谷歌浏览器安装octotree插件

    Octotree Chrome安装与使用方法 Octotree Chrome作用: 主要使你在github查看项目时可以清晰明了的看到项目的结构以及具体代码,使下载代码更具有目的性,减少不必要代码的下 ...

  4. TCP路由网络通信

    路由器 实现跨网段通信   路由器的工作原理是基于路由器中的路由表来实现数据包的路径选择 当路由器收到一个数据包的时候,会读取数据包的目标IP地址,根据目标IP地址来匹配路由表中的规则 单个路由器不会 ...

  5. 用PE系统安装原版XP

    方法:直接运行Winnt32程序进行XP原版系统安装.    [1].在PE系统中将XP SP3系统镜像ISO文件从U盘上复制到硬盘的非系统分区后,用PE所带WinRAR程序将该ISO镜像中的I386 ...

  6. 云计算概述及Centos7下安装kvm虚拟机

    云计算(cloud computing)是基于互联网的相关服务的增加.使用和交付模式,通常涉及通过互联网来提供动态易扩展且经常是虚拟化的资源 云计算到底是什么? 按定义:云计算指的是一种使用模式,是基 ...

  7. 1: process

    https://blogs.sap.com/2013/08/20/creating-a-search-page-sap-crm-70-ehp-1/ https://www.cnblogs.com/sa ...

  8. Linux下安装zookeeper集群(奇数个)

    1.  解压zookeeper压缩包 2.  data里创建“myid”文件(命令touch myid),内容是1(命令 echo 1 >> myid) 3.  zoo.cnf里配置dat ...

  9. wordvector to sentence vector

    wordvector已经通过word2vec训练出来了,可是如何通过WV得到SV(Sentence Vector)? 思路1: 直接将句子的向量叠加取平均:效果很不好,每个词没有考虑权重,获取的向量会 ...

  10. 加载更多的ajax 字符串拼接

    https://www.cnblogs.com/52fhy/p/5405541.html