首页 > 代码库 > 利用QPainter绘制散列图

利用QPainter绘制散列图

【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.cpp11 12 HEADERS  += mainwindow.h13 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 Ui12 {13     class MainWindow;14 }15 16 class MainWindow : public QMainWindow17 {18     Q_OBJECT19 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绘制散列图