此篇内容主要实现了读取电阻数据并绘制曲线图,详细介绍见博客Qt5绘制曲线图(以阻值曲线为例)-CSDN博客
完整代码如下:
#include"plotwindow.h"
#include"ui_TcpServer.h"
#include<cstdlib>
#include<ctime>
#define inf 0x3f3f3f3f
//初始化历史电阻率图形窗口
plotWindow::plotWindow(QWidget* parent)
{
n = 30;
image = QImage(650, 320, QImage::Format_RGB32); //画布的初始化大小设为600*300,使用32位颜色
QColor backColor = qRgb(255, 255, 255); //画布初始化背景色使用白色
setFixedSize(650, 320);
image.fill(backColor);//对画布进行填充
int i;
for (i = 0; i < n; i++)//初始化数组
{
a[i] = 1000;
}
}
bool plotWindow::init(){
QColor backColor = qRgb(255, 255, 255); //画布初始化背景色使用白色
image.fill(backColor);//对画布进行填充
}
//从文件读取历史电阻率数据
bool plotWindow::file_open()
{
int i = 0; int j = 0;
int temp[2048];
fp = fopen("data.txt", "r");//以只读模式打开文件并将其句柄存储在 fp 中
if (fp == NULL)
{
printf("data.txt open is error\n");
return false;
}
else{printf("data.txt open is ok\n");}
int ch;
ch = fgetc(fp); //首先从文件中读取,判断是不是文件结束符EOF
if (ch == EOF)
{printf("nothing\n");} //如果是直接关闭文件退出
rewind(fp); //如果不是,让文件内部的指针重新指向文件开头
while (!feof(fp))//将文件中读取的数据存储到数组a中
{
fscanf(fp, "%d ", &temp[i]);
i = i + 1;
}
i = i - 30;
for (j = 0; j < n; j++){a[j] = temp[i + j];}
fclose(fp);
return true;
}
void plotWindow::Paint()
{
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing, true);//设置反锯齿模式,使图像更平滑
int pointx = 50, pointy = 300;//确定坐标轴起点坐标
int height = 260,width = 580 - pointx ;//根据画布大小确定坐标轴宽度跟高度
//绘制坐标轴 坐标轴原点(35,280)
painter.drawRect(5, 5, 590, 310);//外围的矩形,从(5,5)起,到(590,310)结束
painter.drawLine(pointx, pointy, width + pointx, pointy);//坐标轴x宽度为width
painter.drawLine(pointx, pointy - height, pointx, pointy);//坐标轴y高度为height
srand(time(NULL));
//获得数据中最大值和最小值、平均数
double sum = 0;
double ave = 0;
int max = 0;
int min = inf;
int maxpos = 0, minpos = 0;
for (int i = 0; i < n; i++)
{
sum += a[i];
if (a[i] > max) {max = a[i];maxpos = i;}
if (a[i] < min) {min = a[i];minpos = i;}
}
ave = sum / n;
//计算 x 轴和 y 轴的缩放系数:kx 是图像宽度除以数据点数量减去 1;ky 是图像高度除以数据中的最大值
double kx = (double)width / (n - 1);
double ky = (double)height / (max*2);
QPen pen, penPoint;
pen.setColor(Qt::black);
pen.setWidth(2);
penPoint.setColor(Qt::blue);
penPoint.setWidth(5);
for (int i = 0; i < n - 1; i++)
{
//y轴是倒着的,y轴坐标要pointy-a[i]*ky
painter.setPen(pen);//黑色用于连线
painter.drawLine(pointx + kx * i, pointy - a[i] * ky, pointx + kx * (i + 1), pointy - a[i + 1] * ky);
painter.setPen(penPoint);//蓝色用于标记各个点
painter.drawPoint(pointx + kx * i, pointy - a[i] * ky);
}
painter.drawPoint(pointx + kx * (n - 1), pointy - a[n - 1] * ky);//绘制最后一个点
//绘制平均线
QPen penAve;
penAve.setColor(Qt::red);
penAve.setWidth(2);
penAve.setStyle(Qt::DotLine);
painter.setPen(penAve);
painter.drawLine(pointx, pointy - ave * ky, pointx + width, pointy - ave * ky);
//绘制最大值和最小值
QPen penMaxMin;
penMaxMin.setColor(Qt::darkGreen);//暗绿色
painter.setPen(penMaxMin);
painter.drawText(pointx + kx * maxpos - kx, pointy - a[maxpos] * ky - 5,
"max " + QString::number(max));
painter.drawText(pointx + kx * minpos - kx, pointy - a[minpos] * ky + 15,
"min " + QString::number(min));
penMaxMin.setColor(Qt::red);
penMaxMin.setWidth(7);
painter.setPen(penMaxMin);
painter.drawPoint(pointx + kx * maxpos, pointy - a[maxpos] * ky);//标记最大值点
painter.drawPoint(pointx + kx * minpos, pointy - a[minpos] * ky);//标记最小值点
//绘制刻度线
QPen penDegree;
penDegree.setColor(Qt::black);
penDegree.setWidth(2);
painter.setPen(penDegree);
//画上x轴刻度线
for (int i = 0; i < 10; i++)//分成10份
{
//选取合适的坐标,绘制一段长度为4的直线,用于表示刻度
painter.drawLine(pointx + (i + 1) * width / 10, pointy, pointx + (i + 1) * width / 10, pointy - 4);
painter.drawText(pointx + (i + 0.8) * width / 10,
pointy + 15, QString::number((int)((i + 1) * ((double)n / 10))));
}
//y轴刻度线
double _maStep = (double)max/ 10;//y轴刻度间隔需根据最大值来表示
for (int i = 0; i < 10; i++)
{
//确定一个位置,然后画一条短短的直线表示刻度。
painter.drawLine(pointx, pointy - (i + 1) * height / 10,
pointx + 4, pointy - (i + 1) * height / 10);
painter.drawText(pointx - 43, pointy - (i + 0.85) * height / 10,
QString::number((int)(_maStep * (i + 1))));
}
}
plotWindow::~plotWindow()
{
}