【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. 洛谷P1955 程序自动分析 [NOI2015] 并查集

    正解:并查集+离散化 解题报告: 传送门! 其实题目还挺水的,,,但我太傻逼了直接想挂了,,,所以感觉还是有个小坑点所以还是写个题解记录下我的傻逼QAQ 首先这题一看,就长得很像NOIp关押罪犯?然后 ...

  2. PyQt5学习笔记----标准文件打开保存框QFileDialog

    单个文件打开 QFileDialog.getOpenFileName()多个文件打开 QFileDialog.getOpenFileNames() 文件夹选取     QFileDialog.getE ...

  3. CentOS 系列安装 Docker

    CentOS6对于 CentOS6,可以使用 EPEL 库安装 Docker,命令如下$ sudo yum install http://mirrors.yun-idc.com/epel/6/i386 ...

  4. linux init命令

    init命令用于切换到指定的运行级别,用法如下: [root@localhost ~]# init //关机 [root@localhost ~]# init //切换到单用户模式/救援模式 [roo ...

  5. mysql 操作sql语句 目录

    mysql 操作sql语句 操作数据库 mysql 操作sql语句 操作数据表 mysql 操作sql语句 操作数据表中的内容/记录

  6. git出现warning: LF will be replaced by CRLF的解决方法

    今天ytkah用git上传文件的时候出现了warning: LF will be replaced by CRLF的错误,具体信息如下,这是因为跨平台开发下产生的.由于编辑器的不同或者Windows程 ...

  7. 016-插件使用-head

    一.安装以及概览 elasticsearch-head将是一款专门针对于elasticsearch的客户端工具 elasticsearch-head配置包,下载地址:https://github.co ...

  8. 流程控制之if...else

    # #如果:男的年龄>49,那么:小哥哥## age_of_boy = 50# if age_of_boy > 49:# print('小哥哥你好')### # 如果:女人的年龄>3 ...

  9. abap函数返回结构体类型

    1: 定义一个结构体 T-CODE   se11 2: 选择 structure 3:输入相应的字段 4:激活 5:创建一个function module zfm_return_table,返回类型为 ...

  10. sap component 中各个组件的关系

    1: