码迷,mamicode.com
首页 > 其他好文 > 详细

利用QPainter绘制散列图

时间:2017-05-19 21:12:01      阅读:1051      评论:0      收藏:0      [点我收藏+]

标签:高度   ima   最大值   分析   设置   double   32位   begin   结构   

【1】实例代码

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

技术分享

(2)工程pro文件

 1 QT       += core gui
 2 
 3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 4 
 5 TARGET = painter
 6 TEMPLATE = app
 7 
 8 
 9 SOURCES += main.cpp10         mainwindow.cpp
11 
12 HEADERS  += mainwindow.h
13 
14 FORMS    += mainwindow.ui

(3)头文件

 1 #ifndef MAINWINDOW_H
 2 #define MAINWINDOW_H
 3 
 4 #include <QtGui>
 5 #include <QPaintEvent>
 6 #include <QMainWindow>
 7 
 8 #include <ctime>
 9 #include <cstdlib>
10 
11 namespace Ui
12 {
13     class MainWindow;
14 }
15 
16 class MainWindow : public QMainWindow
17 {
18     Q_OBJECT
19 
20 public:
21     explicit MainWindow(QWidget *parent = 0);
22     ~MainWindow();
23 
24     void Paint();
25 
26 protected:
27     void paintEvent(QPaintEvent *);
28 
29 private:
30     Ui::MainWindow *ui;
31     QImage image;
32 };
33 
34 #endif // MAINWINDOW_H

(4)实现文件

  1 #include "mainwindow.h"
  2 #include "ui_mainwindow.h"
  3 
  4 #define POINTSNUM 10
  5 #define LowerFactor 0.8
  6 #define UpperFactor 1.2
  7 
  8 typedef struct Data
  9 {
 10     double m_span;
 11     double m_maxScale;
 12     double m_minScale;
 13     QVector<double>  m_vectorData;
 14 
 15     Data() : m_span(0.0), m_maxScale(0.0), m_minScale(0.0)
 16     {
 17         m_vectorData.resize(POINTSNUM);
 18     }
 19     void analyse()
 20     {
 21         m_maxScale = (*(std::max_element(m_vectorData.begin(), m_vectorData.end()))) * UpperFactor;
 22         m_minScale = (*(std::min_element(m_vectorData.begin(), m_vectorData.end()))) * LowerFactor;
 23         m_span = m_maxScale - m_minScale;
 24     }
 25 }DataInfo;
 26 
 27 MainWindow::MainWindow(QWidget *parent)
 28     : QMainWindow(parent),
 29       ui(new Ui::MainWindow)
 30 {
 31     ui->setupUi(this);
 32     ui->mainToolBar->setVisible(false);
 33 
 34     resize(1000, 730); // 窗体大小 宽度1000 高度730
 35 
 36     image = QImage(980, 700, QImage::Format_RGB32);  // 画布的初始化大小设为,使用32位颜色
 37     QColor backColor = qRgb(255, 255, 255);    // 画布初始化背景色使用白色
 38     image.fill(backColor); // 对画布进行填充
 39 
 40     Paint();
 41 }
 42 
 43 void MainWindow::Paint()
 44 {
 45     // (1)确定位置区域
 46     QPainter painter(&image);
 47     painter.setRenderHint(QPainter::Antialiasing, true); // 设置反锯齿模式
 48 
 49     // 确定坐标轴起点坐标
 50     int pointx = 80, pointy = 650;
 51 
 52     // 确定坐标轴宽度和高度,上文已定义画布大小,宽高依此而定。
 53     int width = 980 - pointx - 70;  // 宽度 = 画布宽度 - 坐标起点x - 右端间隙
 54     int height = 700 - 2 * 50;      // 高度 = 画布高度 - 上下端的间隙高度
 55 
 56     // 绘制视图区域
 57     // 即外围的矩形(由左上角与右下角的两个点确定一个矩形)
 58     painter.drawRect(10, 10, 980 - 10, 700 - 10);
 59 
 60     // 绘制X、Y1、Y2轴
 61     QPointF xStartPoint(pointx, pointy);
 62     QPointF xEndPoint(width + pointx, pointy);
 63     painter.drawLine(xStartPoint, xEndPoint); // 坐标轴x宽度为width
 64 
 65     QPointF y1StartPoint(pointx, pointy - height);
 66     QPointF y1EndPoint(pointx, pointy);
 67     painter.drawLine(y1StartPoint, y1EndPoint); // 坐标轴y1高度为height
 68 
 69     QPointF y2StartPoint(pointx + width, pointy - height);
 70     QPointF y2EndPoint(pointx + width, pointy);
 71     painter.drawLine(y2StartPoint, y2EndPoint); // 坐标轴y2高度为height
 72 
 73     // (2)获得数据并分析最大值与最小值
 74     DataInfo vectorX, vectorY1, vectorY2; // 数据储存在容器中,大小为POINTSNUM
 75 
 76     // 模拟随机数据
 77     srand((int)time(NULL));
 78     for(int i = 0; i < POINTSNUM; ++i)
 79     {
 80         vectorX.m_vectorData[i] = rand() % 100 + 20;
 81         vectorY1.m_vectorData[i] = rand() % 40 + 10;
 82         vectorY2.m_vectorData[i] = rand() % 60 + 20;
 83     }
 84 
 85     vectorX.analyse();
 86     vectorY1.analyse();
 87     vectorY2.analyse();
 88 
 89     double kx = (double)(width / vectorX.m_span); // x轴的系数
 90     double ky1 = (double)(height / vectorY1.m_span);  // y1方向的比例系数
 91     double ky2 = (double)(height / vectorY2.m_span);  // y2方向的比例系数
 92 
 93     // (3)绘制点
 94     QPen penPointY1, penPointY2;
 95     penPointY1.setColor(Qt::blue);
 96     penPointY1.setWidth(5);
 97 
 98     penPointY2.setColor(Qt::red);
 99     penPointY2.setWidth(5);
100 
101     for (int i = 0; i < POINTSNUM; ++i)
102     {
103         double dXStart = pointx + kx * (vectorX.m_vectorData[i] - vectorX.m_minScale);
104         painter.setPen(penPointY1); // 蓝色的笔,用于标记Y1各个点
105         painter.drawPoint(dXStart, pointy - (vectorY1.m_maxScale - vectorY1.m_vectorData[i]) * ky1);
106 
107         painter.setPen(penPointY2); // 红色的笔,用于标记Y2各个点
108         painter.drawPoint(dXStart, pointy - (vectorY2.m_maxScale - vectorY2.m_vectorData[i]) * ky2);
109     }
110 
111     // (4) 绘制刻度线
112     QPen penDegree;
113     penDegree.setColor(Qt::black);
114     penDegree.setWidth(2);
115     painter.setPen(penDegree);
116 
117     // x轴刻度线
118     for (int i = 0; i < POINTSNUM; ++i) // 分成10份
119     {
120 //        // 选取合适的坐标,绘制一段长度为4的直线,用于表示刻度
121 //        painter.drawLine(pointx + (i + 1) * width/10, pointy,
122 //                         pointx + (i+1)*width/10, pointy + 4);
123 
124         painter.drawText(pointx + (i+0.7)*width / 10, pointy + 12,
125                          QString::number((int)((i+1)*((double)vectorX.m_span/10))));
126     }
127 
128     xStartPoint.setX(pointx);
129     xStartPoint.setY(pointy + 20);
130     xEndPoint.setX(pointx + width);
131     xEndPoint.setY(pointy + 20);
132     painter.drawLine(xStartPoint, xEndPoint);
133 
134     painter.drawText(pointx + width/2, pointy + 35, QString("X"));
135 
136     // y1轴刻度线和值
137     for (int i = 0; i < POINTSNUM; ++i)
138     {
139         // 代码较长,但是掌握基本原理即可。
140         // 主要就是确定一个位置,然后画一条短短的直线表示刻度。
141 
142 //        painter.drawLine(pointx, pointy-(i+1)*height/10,
143 //                         pointx-4, pointy-(i+1)*height/10);
144 
145         painter.drawText(pointx - 25, pointy - (i+0.85)*height/10,
146                          QString::number((int)(vectorY1.m_span*(i+1))));
147     }
148 
149     y1StartPoint.setX(pointx - 35);
150     y1StartPoint.setY(pointy - height);
151 
152     y1EndPoint.setX(pointx - 35);
153     y1EndPoint.setY(pointy);
154     painter.drawLine(y1StartPoint, y1EndPoint);
155 
156     painter.drawText(pointx - 55, pointy - height/2, QString("Y1"));
157 
158     // y2轴刻度线和值
159     for (int i = 0; i < POINTSNUM; ++i)
160     {
161 //        painter.drawLine(pointx + width, pointy-(i+1)*height/10,
162 //                         pointx + width + 4, pointy-(i+1)*height/10);
163 
164         painter.drawText(pointx + width + 10, pointy - (i+0.85)*height/10,
165                          QString::number((int)(vectorY2.m_span*(i+1))));
166     }
167 
168     y2StartPoint.setX(pointx + width + 40);
169     y2StartPoint.setY(pointy - height);
170 
171     y2EndPoint.setX(pointx + width + 40);
172     y2EndPoint.setY(pointy);
173     painter.drawLine(y2StartPoint, y2EndPoint);
174 
175     painter.drawText(pointx + width + 50, pointy - height/2, QString("Y2"));
176 
177     // (5)绘制网格
178     QPen penDotLine;
179     penDotLine.setStyle(Qt::DotLine);
180     painter.setPen(penDotLine);
181     for (int i = 0; i < POINTSNUM; ++i)
182     {
183         // 垂直线
184         painter.drawLine(pointx + (i+1)* width/10, pointy,
185                          pointx + (i+1)* width/10, pointy - height);
186         // 水平线
187         painter.drawLine(pointx, pointy-(i+1)*height/10,
188                          pointx + width, pointy-(i+1)*height/10);
189     }
190 }
191 
192 MainWindow::~MainWindow()
193 {
194     delete ui;
195 }
196 
197 void MainWindow::paintEvent(QPaintEvent *)
198 {
199     QPainter painter(this);
200     painter.drawImage(0, 0, image);
201 }

 (5)main文件

 1 #include "mainwindow.h"
 2 #include <QApplication>
 3 
 4 int main(int argc, char *argv[])
 5 {
 6     QApplication a(argc, argv);
 7     MainWindow w;
 8     w.show();
 9 
10     return a.exec();
11 }

【2】效果图

运行结果图如下:

技术分享

Good Good Study, Day Day Up.

顺序 选择 循环 总结

利用QPainter绘制散列图

标签:高度   ima   最大值   分析   设置   double   32位   begin   结构   

原文地址:http://www.cnblogs.com/Braveliu/p/6880099.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!