Qt5编写的一个推力传感器静态性能计算程序
2017-11-03 00:49
671 查看
最近一门课设做推力传感器设计和标定,要用到一个辅助程序,所以就用Qt5写了一个界面的计算程序,也分享上来供大家参考一下思路。
小程序:
数据处理方法在这里:链接:http://pan.baidu.com/s/1jIagziu 密码:9ya5
exe程序在这里:链接:http://pan.baidu.com/s/1c1YqNrq 密码:09gy
使用时,先输入校准点个数K和校准循环次数R,从表格(QTableWidget)输入原始数据,程序计算出一系列统计参数并从输出框输出,在下方绘制校准曲线。
在QPixmap绘图,之后用QLabel加载,也不需要动态更新,没有用paintevent (有没有大神,这样做有问题吗?)
为了方便输出,用了一个二维数组vector<qstringlist>保存计算结果,编写过程可能有些繁琐
头文件:
mainwidget.h
compute.h
源文件:
main.cpp
mainwidget.cpp
compute.cpp
mainwidget.ui:
控件布局:
最终效果(虚构的数据):
就这些,除 了计算各种统计量有些繁琐以外,没有什么难的地方。以上可供Qt初学者参考,我也只是个菜鸟,可能有很多地方写得不好,欢迎批评指正
小程序:
数据处理方法在这里:链接:http://pan.baidu.com/s/1jIagziu 密码:9ya5
exe程序在这里:链接:http://pan.baidu.com/s/1c1YqNrq 密码:09gy
使用时,先输入校准点个数K和校准循环次数R,从表格(QTableWidget)输入原始数据,程序计算出一系列统计参数并从输出框输出,在下方绘制校准曲线。
在QPixmap绘图,之后用QLabel加载,也不需要动态更新,没有用paintevent (有没有大神,这样做有问题吗?)
为了方便输出,用了一个二维数组vector<qstringlist>保存计算结果,编写过程可能有些繁琐
头文件:
mainwidget.h
#ifndef MAINWIDGET_H #define MAINWIDGET_H #include <QtWidgets/QWidget> #include "ui_mainwidget.h" class mainWidget : public QWidget { Q_OBJECT public: mainWidget(QWidget *parent = 0); ~mainWidget(); private: Ui::mainWidgetClass ui; //私有变量 int K = 0, R = 0;//校准点个数,校准循环次数 //QPixmap pixmap; //函数 void mainWidget::setHeaders();//设置表头 void mainWidget::print(const std::vector<std::vector<double>>& outputData); void mainWidget::paintCurve(const std::vector<std::vector<double>>& tableData, const std::vector<std::vector<double>>& outputData);
//槽函数 void mainWidget::on_spinBoxK_valueChanged(); void mainWidget::on_spinBoxR_valueChanged(); void mainWidget::on_buttonClearTable_clicked(); void mainWidget::on_buttonClearTexeEdit_clicked(); void mainWidget::on_buttonCompute_clicked(); }; #endif // MAINWIDGET_H
compute.h
#ifndef COMPUTE_H #define COMPUTE_H #include <vector> void compute(const std::vector<std::vector<double>>& tableData, std::vector<std::vector<double>>& outputData); #endif // COMPUTE_H
源文件:
main.cpp
#include "mainwidget.h" #include <QtWidgets/QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); mainWidget w; w.show(); return a.exec(); }
mainwidget.cpp
#include "mainwidget.h" #include "compute.h" #include <QPainter> mainWidget::mainWidget(QWidget *parent) : QWidget(parent) { ui.setupUi(this); //隔行改变背景色 ui.tableWidget->setAlternatingRowColors(true); //ui.labelCurve->setScaledContents(true); //ui.labelCurve->setStyleSheet("QLabel{background:rgb(0,0,0);color:white;}"); //初始化spinbox K = ui.tableWidget->rowCount(); R = (ui.tableWidget->columnCount() - 1)/ 2; ui.spinBoxNumK->setValue(K); ui.spinBoxNumR->setValue(R); //设置表头 setHeaders(); connect(ui.spinBoxNumK, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &mainWidget::on_spinBoxK_valueChanged); connect(ui.spinBoxNumR, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &mainWidget::on_spinBoxR_valueChanged); connect(ui.buttonClearTable, &QPushButton::clicked, this, &mainWidget::on_buttonClearTable_clicked); connect(ui.buttonClearTextEdit, &QPushButton::clicked, this, &mainWidget::on_buttonClearTexeEdit_clicked); connect(ui.buttonCompute, &QPushButton::clicked, this, &mainWidget::on_buttonCompute_clicked); } mainWidget::~mainWidget() { } void mainWidget::setHeaders() { //设置表头 QStringList headers; headers.append(QString("Xi/kN")); for (int i = 1; i <= R; i++) { headers.append(QString("Yci") + QString("%1/mV").arg(i)); headers.append(QString("Yfi") + QString("%1/mV").arg(i)); } ui.tableWidget->setHorizontalHeaderLabels(headers); } void mainWidget::print(const std::vector<std::vector<double>>& outputData)//输出 { for (int i = 0; i < K; i++) { ui.textEdit->append(QString(QString::fromLocal8Bit("-----------------------"))); ui.textEdit->append(QString(QString::fromLocal8Bit("第%1个校准点:")).arg(i + 1)); ui.textEdit->append(QString(QString::fromLocal8Bit("正行程平均值:%1")).arg(outputData.at(0).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("反行程平均值:%1")).arg(outputData.at(1).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("正、反行程总平均值:%1")).arg(outputData.at(2).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("最小二乘值:%1")).arg(outputData.at(4).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("线性差值ΔL:%1")).arg(outputData.at(5).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("迟滞性ΔH:%1")).arg(outputData.at(6).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("正行程标准差Sc:%1")).arg(outputData.at(7).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("反行程标准差Sf:%1")).arg(outputData.at(8).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("正行程系统偏差Bc:%1")).arg(outputData.at(9).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("反行程系统偏差Bf:%1")).arg(outputData.at(10).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("不确定度Bc+tSc:%1")).arg(outputData.at(11).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("不确定度Bf+tSf:%1")).arg(outputData.at(12).at(i))); ui.textEdit->append(QString(QString::fromLocal8Bit("-----------------------"))); } ui.textEdit->append(QString(QString::fromLocal8Bit("最终结果:"))); ui.textEdit->append(QString(QString::fromLocal8Bit("y = bx + a,其中:"))); ui.textEdit->append(QString(QString::fromLocal8Bit("b = %1")).arg(outputData.at(3).at(0))); ui.textEdit->append(QString(QString::fromLocal8Bit("a = %1")).arg(outputData.at(3).at(1))); //ui.textEdit->append(QString(QString::fromLocal8Bit("YF:%1")).arg(outputData.at(13).at(0))); //ui.textEdit->append(QString(QString::fromLocal8Bit("t_alpha:%1")).arg(outputData.at(13).at(1))); ui.textEdit->append(QString(QString::fromLocal8Bit("重复性:%1")).arg(outputData.at(13).at(2))); ui.textEdit->append(QString(QString::fromLocal8Bit("相对不确定度:%1")).arg(outputData.at(13).at(3))); ui.textEdit->append(QString(QString::fromLocal8Bit("非线性:%1")).arg(outputData.at(13).at(4))); ui.textEdit->append(QString(QString::fromLocal8Bit("迟滞性:%1")).arg(outputData.at(13).at(5))); } void mainWidget::paintCurve(const std::vector<std::vector<double>>& tableData, const std::vector<std::vector<double>>& outputData)//绘制曲线 { QPixmap pixmap(ui.labelCurve->width(), ui.labelCurve->height()); pixmap.fill(Qt::black);//黑色背景 QPainter p(&pixmap);//开始绘图---------------------------------------------------------- //定义边距及图像大小 int left = 35; int up = 10; int right = 15; int down = 20; int imgWidth = ui.labelCurve->width() - left - right; int imgHeight = ui.labelCurve->height() - up - down; //白色边框 p.setPen(Qt::white); p.drawRect(left, up, imgWidth, imgHeight); //绿色网格线 p.setPen(QPen(Qt::green, 1, Qt::DotLine)); for (int i = left + imgWidth / 10; i <= left + imgWidth * 9 / 10; i += imgWidth / 10) { p.drawLine(i, up, i, up + imgHeight); } for (int j = up + imgHeight / 10; j <= up + imgHeight * 9 / 10; j += imgHeight / 10) { p.drawLine(left, j, left + imgWidth, j); } //坐标值 p.setPen(QPen(Qt::white)); p.drawText(left - 3, up + imgHeight + 15, QString("0")); p.drawText(left - 34, up + imgHeight + 5, QString("0.000")); double maxX = tableData.at(K - 1).at(0);//X坐标最大值 for (int i = 1; i <= 10; i++) { p.drawText(left - 15 + i * imgWidth / 10, up + imgHeight + 15, QString::number(i * maxX / 10,'f',2)); } double maxY = tableData.at(K - 1).at(1) * 1.1;//Y坐标最大值 for (int j = 1; j <= 10; j++) { p.drawText(left - 34, up + imgHeight + 5 - j * imgHeight / 10, QString::number(j * maxY / 10, 'f', 3)); } //工作曲线 int numA = 0;//左截距 像素坐标值 int numB = 0;//右截距 像素坐标值 numA = outputData.at(3).at(1) / maxY * imgHeight; numB = (outputData.at(3).at(0) * tableData.at(K - 1).at(0) + outputData.at(3).at(1)) / maxY * imgHeight; p.setPen(QPen(Qt::yellow, 2)); p.drawLine(left, up + imgHeight - numA, left + imgWidth, up + imgHeight - numB); //数据点 p.setPen(QPen(Qt::red, 2)); for (int i = 0; i < K; i++) { for (int j = 1; j <= 2 * R; j++)//j从1到R { int X; int Y; X = tableData.at(i).at(0) / tableData.at(K - 1).at(0) * imgWidth + left; Y = up + imgHeight - tableData.at(i).at(j) / maxY * imgHeight; p.drawPoint(X,Y); } } p.end();//结束绘图------------------------------------------------------------------- ui.labelCurve->setPixmap(pixmap);//显示 } void mainWidget::on_spinBoxK_valueChanged() { K = ui.spinBoxNumK->value(); ui.tableWidget->setRowCount(K); } void mainWidget::on_spinBoxR_valueChanged() { R = ui.spinBoxNumR->value(); ui.tableWidget->setColumnCount(2 * R + 1); setHeaders(); } void mainWidget::on_buttonClearTable_clicked() { ui.tableWidget->clearContents(); } void mainWidget::on_buttonClearTexeEdit_clicked() { ui.textEdit->clear(); } void mainWidget::on_buttonCompute_clicked() { if (K == 0 || R == 0) return; else//若列表不为空 { std::vector<std::vector<double>> tableData(K, std::vector<double>(2 * R + 1));//表格原始输入数据 //按列遍历读取并检查数据 for (int i = 0; i < K; i++) { for (int j = 0; j < 2 * R + 1; j++) { if (ui.tableWidget->item(i, j) == NULL) return;//若表格有填写空缺,退出函数 else//单元格非空,读取数据 { bool ok = true; tableData.at(i).at(j) = ui.tableWidget->item(i, j)->text().toDouble(&ok); //ui.textEdit->append(QString("%1").arg(tableData.at(i).at(j))); if (ok == false) return;//若表格输入非double类型,退出函数 } } } //计算并输出 std::vector<std::vector<double>> outputData(17);//用二维数组保存计算结果,见compute.cpp compute(tableData, outputData);//计算 print(outputData);//输出 paintCurve(tableData, outputData);//绘图并显示 //ui.labelCurve->setPixmap(pixmap);//显示 } }
compute.cpp
#include "compute.h" #include <cmath> void compute(const std::vector<std::vector<double>>& tableData, std::vector<std::vector<double>>& outputData) { const int K = tableData.size(); const int R = (tableData.at(0).size() - 1) / 2; double temp1 = 0;//中间临时变量 double temp2 = 0; //0正行程平均值 //1反行程平均值 //2总平均值 for (int i = 0; i < K; i++) { for (int j = 1; j <= R; j++)//j从1到R { temp1 += tableData.at(i).at(2 * j - 1);//temp1、temp2表示正反行程Y的和 temp2 += tableData.at(i).at(2 * j); } outputData.at(0).push_back(temp1 / R);//正行程平均值,一共push_back了K次 outputData.at(1).push_back(temp2 / R);//反行程平均值 outputData.at(2).push_back((temp1 + temp2) / R / 2);//总平均值 temp1 = 0;//置零 temp2 = 0; } //3求a 求b double sum_x = 0; double sum_x2 = 0; double sum_y = 0; double sum_xy = 0; double a = 0, b = 0; for (int i = 0; i < K; i++) { sum_x += tableData.at(i).at(0); sum_x2 += tableData.at(i).at(0) * tableData.at(i).at(0); sum_y += outputData.at(2).at(i); sum_xy += tableData.at(i).at(0) * outputData.at(2).at(i); } b = (K * sum_xy - sum_x * sum_y) / (K * sum_x2 - sum_x * sum_x); a = sum_y / K - b * sum_x / K; outputData.at(3).push_back(b); outputData.at(3).push_back(a); //4最小二乘值bx+a //5线性差值 //6迟滞性 //9正行程系统偏差Bc //10反行程系统偏差Bf for (int i = 0; i < K; i++) { outputData.at(4).push_back(b * tableData.at(i).at(0) + a); outputData.at(5).push_back(std::abs(outputData.at(2).at(i) - outputData.at(4).at(i))); outputData.at(6).push_back(std::abs(outputData.at(0).at(i) - outputData.at(1).at(i))); outputData.at(9).push_back(std::abs(outputData.at(0).at(i) - outputData.at(4).at(i))); outputData.at(10).push_back(std::abs(outputData.at(1).at(i) - outputData.at(4).at(i))); } //7正行程标准差Sc //8反行程标准差Sf temp1 = 0;//temp1、temp2表示正反行程(Yi-Y_average)^2的和 temp2 = 0;//置零 for (int i = 0; i < K; i++)//第i个校准点 { for (int j = 1; j <= R; j++)//j从1到R { temp1 += (tableData.at(i).at(2 * j - 1) - outputData.at(0).at(i)) * (tableData.at(i).at(2 * j - 1) - outputData.at(0).at(i)); temp2 += (tableData.at(i).at(2 * j) - outputData.at(1).at(i)) * (tableData.at(i).at(2 * j) - outputData.at(1).at(i)); } outputData.at(7).push_back(std::sqrt(temp1 / (R - 1)));//正行程标准差 outputData.at(8).push_back(std::sqrt(temp2 / (R - 1)));//反行程标准差 } //11 Bc+t0.95Sc //12 Bf+t0.95Sf double t_alpha = 0;//t_0.95 switch (R) { case 2: { t_alpha = 12.706; break; } case 3: { t_alpha = 4.303; break; } case 4: { t_alpha = 3.182; break; } case 5: { t_alpha = 2.776; break; } case 6: { t_alpha = 2.571; break; } case 7: { t_alpha = 2.447; break; } case 8: { t_alpha = 2.365; break; } } for (int i = 0; i < K; i++) { outputData.at(11).push_back(outputData.at(9).at(i) + t_alpha * outputData.at(7).at(i));//11 Bc+t0.95Sc outputData.at(12).push_back(outputData.at(10).at(i) + t_alpha * outputData.at(8).at(i));//12 Bf+t0.95Sf } //13 0:Yfc = b * (Xk - X1)、1:t_alpha、2:重复性、3:不确定度、4:非线性、5:迟滞 outputData.at(13).push_back(b * (tableData.at(K - 1).at(0) - tableData.at(0).at(0))); outputData.at(13).push_back(t_alpha); double maxS = outputData.at(7).at(0);//最大标准差 double maxU = outputData.at(11).at(0);//不确定度 double maxL = outputData.at(5).at(0);//最大线性差值 double maxH = outputData.at(6).at(0);//最大迟滞性 for (int i = 0; i < K; i++) { if (outputData.at(7).at(i) > maxS) maxS = outputData.at(7).at(i); if (outputData.at(8).at(i) > maxS) maxS = outputData.at(8).at(i); if (outputData.at(11).at(i) > maxU) maxU = outputData.at(11).at(i); if (outputData.at(12).at(i) > maxU) maxU = outputData.at(12).at(i); if (outputData.at(5).at(i) > maxL) maxL = outputData.at(5).at(i); if (outputData.at(6).at(i) > maxH) maxH = outputData.at(6).at(i); } outputData.at(13).push_back(t_alpha * maxS / outputData.at(13).at(0));//重复性2 outputData.at(13).push_back(maxU / outputData.at(13).at(0));//相对不确定度3 outputData.at(13).push_back(maxL / outputData.at(13).at(0));//非线性4 outputData.at(13).push_back(maxH / outputData.at(13).at(0));//迟滞5 }
mainwidget.ui:
控件布局:
最终效果(虚构的数据):
就这些,除 了计算各种统计量有些繁琐以外,没有什么难的地方。以上可供Qt初学者参考,我也只是个菜鸟,可能有很多地方写得不好,欢迎批评指正
相关文章推荐
- [4.21]编写一个程序,已有若干个学生的数据,包括学号、姓名、成绩、要求输出这些学生的数据并计算出学生人数和平均成绩(要求将学生人数和总成绩用静态数据成员表示)。
- 编写一个计算某个月份的天数程序,请用if-else条件语句实现。要求根据用户输入的月份,判断出月份所包含的天数。
- 1.已知接口ComputerAverage,和主类Estimator,编写程序完成SongGame和School类。SongGame类能够根据歌手得分去掉一个最高分,去掉一个最低分,计算其余得分的平均
- n的阶乘;计算1!+2!+3!+4!+...+10!;编写代码,演示多个字符从两边移动,向中间汇聚;求ax^2+bx+c=0的解;写一个程序返回参数二进制中1的个数;6.求两个数的最大公约数。
- 编写一个程序,实现设置上月、本月电表读数,显示上月、本月电表读数,计算并显示本月用电数。假设每度电的价格为1.2元,计算并显示本月电费。
- 题目: 编写一个程序,实现设置上月、本月电表读数,显示上月、本月电表读数,计算并显示本月用电数。假设每度电的价格为1.2元,计算并显示本月电费。
- 编写一个程序,要求用户输入最多10个高尔夫成绩,并将其存储在一个数组中。 程序允许用户提早结束输入,并在一行上显示所有成绩,然后报告平均成绩。 请使用3个数组处理函数来分别进行输入、显示和计算
- 编写一个程序,实现设置上月、本月电表读数,显示上月、本月电表读数,计算并显示本月用电数。 *假设每度电的价格为1.2元,计算并显示本月电费
- 编写一个程序,实现设置上月、本月电表读数,显示上月、本月电表读数,计算并显示本月用电数。 假设每度电的价格为1.2元,计算并显示本月电费
- 黑马程序员---------------------编写程序,该程序启动后用户可以按“yyyy-MM-dd”的格式输入一个日期, * 程序计算这一天是星期几,并且计算出是一年中的第几天
- 编写一个程序,要求用户输入下限整数和一个上限整数,然后,依次计算从下限到上限的每一个整数的平方的加和,最后显示结果
- 编写一个Java程序,计算半径为3.0的圆周长和面积并输出结果
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是 100 的程序,并输出所有的可能性。 例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100
- 编写一个程序,实现显示上月、本月电表读数,计算并显示本月用电数。
- 编写一个最有代表意义的qt程序
- 编写一个程序,计算多少年后清空账户
- 编写一个程序,从标准输入读取一些字符,并把它们写到标准输出上。它同时应该计算checksum值,写在后面
- 编写一个程序,实现设置上月、本月电表读数,显示上月、本月电表读数,计算并显示本月用电数。 假设每度电的价格为1.2元,计算并显示本月电费
- :有一个卡车司机肇事后想逃跑,但是被三个人看见了其车牌号,但是都没看全, 甲说:车牌的前两位是一样的;乙说:车牌的后两位是一样的,但与前两位不一样; 丙说:车牌是一个数字的平方,请编写一个程序计算
- 定义一个结构体变量(包括年、月、日),编写程序,要求输入年月日,程序能够计算并输出改日是本年中的第几天。注意闰年问题。(数组)