目录
说明
一、QTableWidget使用说明
(一)常用成员函数
1.设置行列
2.设置表头 (枚举值查看帮助文档)
3.设置属性
(二)常用信号函数
(三)常用槽函数
二、对excel文件的操作实例
(一)代码头文件
(二)表格设置
1.设置行列
2.设置表头
(三)读取表格
(四)显示表格
(五)计算数据
1.参数初始化
2.计算实现并显示
(六)保存结果
三、补充说明
(一)插入行与删除行功能
1.插入行
2.删除行
(二)QString与double类型互相转换
1.QString转double
2.double转QString
四、结果展示
(一)功能窗口
(二)读取excel表格
(三)高斯计算
(四)保存结果
①本文较长,推荐目录查看自己需要的一部分
②对excel进行读写的代码主要借鉴了b站up主【千秋10000】Qt读取Excel+源码拿走_哔哩哔哩_bilibili
③qtablewidget主要借鉴了csdn【睿科知识云】的文章Qt QTableWidget表格控件的用法(非常详细)_睿科知识云的博客-CSDN博客_qt表格控件
④本文包含:qtablewidget的使用说明和excel的操作实例
⑤如需要源代码,请访问对excel表格文件数据进行读写计算-C++文档类资源-CSDN下载
成员函数 | 功能 |
---|---|
setRowCount(int rows) | 设置行数 |
setColumnCount(int columns) | 设置列数 |
setRowHeight(int row, int height) | 设置指定行高 |
setColumnWidth(int column, int width) | 设置指定列宽 |
成员方法 | 功能 |
---|---|
setHorizontalHeaderLabels(const QStringList &labels) | 设置表格水平表头 |
setVerticalHeaderLabels(const QStringList &labels) | 设置表格竖直表头 |
setStretchLastSection(bool stretch) |
最后一列填满空间 |
setSectionResizeMode(ResizeMode mode) | 设置大小模式 |
成员函数 | 功能 |
---|---|
setEditTriggers(EditTriggers triggers) | 编辑设置 |
setSelectionBehavior(枚举) | 选中行为 |
setSecetionMode(枚举) | 选中模式 |
setFrameShape(Shape) | 设置边框 |
setShowGrid(bool show) | 是否显示网格 |
常数 | 说明 |
---|---|
QAbstractItemView::NoEditTriggers |
不可编辑 |
QAbstractItemView::DoubleClicked |
双击开始编辑 |
QAbstractItemView::AnyKeyPressed |
点击任意键开始编辑 |
常数 | 说明 |
---|---|
QAbstractItemView::SelectItems |
选择单元格 |
QAbstractItemView::SelectRows |
选择整行 |
QAbstractItemView::SelectColumns |
选择整列 |
常数 | 说明 |
---|---|
QAbstractItemView::NoSelection |
不可选中 |
QAbstractItemView::SingleSelection |
选中单个项目 |
常数 | 说明 |
---|---|
QFrame::NoFrame |
无边框 |
QFrame::Box |
设置外边框 |
QFrame::HLine |
设置无边框水平线 |
QFrame::VLine |
设置无边框垂直线 |
常数 | 说明 |
---|---|
true |
显示网格 |
false | 不显示网格 |
信号函数 | 功能 |
---|---|
cellClicked(int row,int column) | 单元格(row,columun)被点击时触发信号, |
cellDoubleClicked(int row,int column) | 单元格(row,columun)被双击时触发信号 |
cellEntered(int row,int column) | 单元格(row,columun)被按下时触发信号 |
cellChanged(int row, int column) | 单元格(row,columun)数据改变时触发信号 |
itemClicked(QTableWidgetItem *item) | 单元格item被点击时触发信号 |
itemDoubleClicked(QTableWidgetItem *item) | 单元格item被双击时触发信号 |
itemEntered(QTableWidgetItem *item) | 单元格item被按下时触发信号 |
itemChanged(QTableWidgetItem *item) | 单元格item数据改变时触发信号 |
槽函数 | 功能 |
---|---|
clear() | 删除表格所有内容,包括表头 |
clearContents() | 删除单元格所有内容,保留表头 |
insertColumn(int column) | 在表格第 column 列的位置插入一个空列 |
insertRow(int row) | 在表格第 row 行的位置插入一个空行 |
removeColumn(int column) | 删除表格的第 column 列,包括该列所有单元格 |
removeRow(int row) | 删除表格的第 row 行,包括该行所有单元格 |
说明:本实例将为全国省份城市的经纬度(b,l)转换为高斯坐标点(x,y)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//设置tablewidget的行列
ui->tableWidget->setRowCount(700);
ui->tableWidget->setColumnCount(5);
//设置表头
ui->tableWidget->setAlternatingRowColors(true); //隔行变色
ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); //选中整行
ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); //自适应
QStringList header; //初始化表头
header<<"省份城市"<<"省份"<<"城市"<<"北纬"<<"东经"; //设置表头内容
ui->tableWidget->setHorizontalHeaderLabels(header);
//读取表格内容
void MainWindow::on_actionopen_triggered()
{
//获取要读取得文件名
QString fileName=QFileDialog::getOpenFileName(this,"读取","C:\\Users\\31188\\Desktop\\GK_calculator/*.xlsx");
if(fileName.isEmpty())
return;
fileName=QDir::toNativeSeparators(fileName);
//打开Excel进程、获取工作簿、工作表、单元格
QAxObject*myExcel=new QAxObject("Excel.application",this);
myExcel->setProperty("DisplayAlerts",false);
QAxObject*workBooks=myExcel->querySubObject("WorkBooks");
workBooks->dynamicCall("Open(const QString&)",fileName);
QAxObject*workBook=myExcel->querySubObject("ActiveWorkBook");
QAxObject*mySheets=workBook->querySubObject("Sheets");
QAxObject*sheet=mySheets->querySubObject("Item(int)",1);
//获取已经使用的单元格区域,并得到行列数
QAxObject*range=sheet->querySubObject("UsedRange");
QAxObject*rows=range->querySubObject("Rows");
QAxObject*colums=range->querySubObject("Columns");
int count_row=rows->dynamicCall("Count").toUInt();
int count_col=colums->dynamicCall("Count").toUInt();
//提取单元格中内容,存放到StringList中
QStringList tableString;
QAxObject*cell;
tableString.clear();
for(int i=1;i<=count_row;i++)
{
QString line;
for(int j=1;j<=count_col;j++)
{
cell=range->querySubObject("Cells(int,int)",i,j);
line+=cell->dynamicCall("Value").toString()+"\t";
}
tableString.append(line);
}
//关闭工作簿、结束进程
workBook->dynamicCall("Close()");
myExcel->dynamicCall("Quit()");
//显示得到的数据
showTableString(tableString);
}
//显示表格内容
void MainWindow::showTableString(const QStringList table)
{
if(table.isEmpty())
return;
QTableWidget*tableWidget=ui->tableWidget;
QStringList header=table.at(0).simplified().split(' ',QString::SkipEmptyParts);
tableWidget->setRowCount(table.count()-1);
tableWidget->setColumnCount(header.count());
tableWidget->setHorizontalHeaderLabels(header);
for(int i=1;isetText(line.at(j));
item->setTextAlignment(Qt::AlignCenter);
tableWidget->setItem(i-1,j,item);
}
QTableWidgetItem*item=tableWidget->item(i-1,header.count()-1);
qreal aver=item->text().toDouble();
item->setText(QString("%1").arg(aver,4,'f',1));
}
}
//公式参数
double L0,l,W,N,P,X,t,x,y;
double pi=3.1415926;
double a=6378136.49,b=6356755.00; //cs2000坐标系
double e=sqrt((pow(a,2)-pow(b,2))/pow(a,2));
double e1 = sqrt((pow(a,2) - pow(b,2)) / pow(b,2));
double t1 = pow(e, 2), t2 = pow(e, 4), t3 = pow(e, 6), t4 = pow(e, 8);
double A0 = 1.0 + (3 / 4.00) * t1 + (45 / 64.00) * t2 + (350 / 512.0) * t3 + (11025/ 16384.0) * t4;
double A2 = -1 / 2.0 * ((3/ 4.0) * t1 + (60 / 64.0) * t2 + (525/ 512.0) * t3 + (17640 / 16384.0) * t4);
double A4 = 1 / 4.0 * ((15 / 64.0) * t2 + (210 / 512.0) * t3 + (8820 / 16384.0) * t4);
double A6 = -1 / 6.0 * ((35 / 512.0) * t3 + (2520 / 16384.0) * t4);
double A8 = 1 / 8.0 * ((315.0 / 16384.0) * t4);
/*
实现思想:①取出想要计算的数据(省份城市、省份、城市等不参与计算,不需要取出)
②将取出的经纬度数据存放在textB和textL中
③此时的textB和textL是QString类,不能直接参与运算
④将textB和textL转换为double类型赋值给B,L并计算出x,y
⑤此时的结果x,y是double类型,需要先转换为qstring再存放进表格
⑥这里采用的方法是在取出数据的for循环中将计算结果x,y逐个替换掉原本的b,l值
*/
void MainWindow::on_actiongszs_triggered()
{
//逐行取出table中的省份城市、省份、城市、北纬、东经
for (int i=0;itableWidget->rowCount();i++) {
QString textB=ui->tableWidget->item(i,3)->text();
QString textL=ui->tableWidget->item(i,4)->text();
//将B,L由qstring类型转换为double类型
double B=QString(textB).toDouble();
double L=QString(textL).toDouble();
//进行高斯投影计算
L0 = int(L/6) * 6 + 3.0;//中央经线经度
l = (L - L0)* pi / 180;//经差 弧度制
W = sqrt(1 - t1 * pow(sin(B), 2));
N = a / W;
t = tan(B);
P = e1 * pow(cos(B), 2);
X = a * (1 - t1) * (A0 * B + A2 * sin(2 * B) + A4 * sin(4 * B) + A6 * sin(6 * B) + A8 * sin(8 * B));
if ( fabs(B - 90 * pi / 180)<0.000000001 )
x = X;
else
x = X + (1.0 / 2.0) * N * t * pow(cos(B), 2) * pow(l, 2) + (1.000 / 24.000000) * N * t * (5 - pow(t, 2) + 9 * P + 4 * pow(P, 2)) * pow(cos(B), 4) * pow(l, 4) + (1.0000000 / 720.00) * N * t * (61.00 - 58.00 * pow(t, 2) + pow(t, 4)) * pow(cos(B), 6) * pow(l, 6);
y = N * cos(B) * l + (1.0000 / 6.00) * N * (1 - pow(t, 2) + P) * pow(cos(B), 3) * pow(l, 3) + (1.0000000 / 120.00) * N * (5.0 - 18.00 * pow(t, 2) + pow(t, 4) + 14 * P - 58 * P * pow(t, 2)) * pow(cos(B), 5) * pow(l, 5);
//将结果x,y转换为qstring类型
QString itemx=QString::number(x,'f',4);
QString itemy=QString::number(y,'f',4);
//将计算最终结果插入到table中
QTableWidgetItem *stringx=new QTableWidgetItem();//创建一个Item
stringx->setText(itemx);//设置内容
ui->tableWidget->setItem(i,3,stringx);//把这个Item加到第i行第3列中
QTableWidgetItem *stringy=new QTableWidgetItem();//创建一个Item
stringy->setText(itemy);//设置内容
ui->tableWidget->setItem(i,4,stringy);//把这个Item加到第i行第4列中
}
QMessageBox::information(this,"信息","计算成功");
}
//保存表格内容
void MainWindow::on_actionsave_triggered()
{
//获取要保存的文件名
QString fileName=QFileDialog::getSaveFileName(this,"保存","C:\\Users\\31188\\Desktop\\GK_calculator/resultFile","*.xlsx");
if(fileName.isEmpty())
return;
fileName=QDir::toNativeSeparators(fileName);
//获取表格行列数
QTableWidget*table=ui->tableWidget;
int rows=table->rowCount();
int columns=table->columnCount();
//获取表头
QStringList header;
for(int i=0;ihorizontalHeaderItem(i)->text());
//打开Excel进程,获取工作簿集合
QAxObject*myExcell=new QAxObject("Excel.application",this);
myExcell->setProperty("DisplayAlerts",false);
QAxObject*workbooks=myExcell->querySubObject("WorkBooks");
workbooks->dynamicCall("Add");
//获取当前工作簿、工作表集合
QAxObject*workbook=myExcell->querySubObject("ActiveWorkBook");
QAxObject*sheets=workbook->querySubObject("Sheets");
//获取当前工作表、设置表名称“Hello”
QAxObject*sheet=sheets->querySubObject("Item(int)",1);
sheet->setProperty("Name","Hello");
//获取单元格
//保存表头
QAxObject*cell;
for(int i=0;iquerySubObject("Cells(int,int)",1,i+1);
cell->setProperty("Value",header.at(i));
}
//保存表内容
for(int i=0;icolumnCount();j++)
{
QTableWidgetItem*item=table->item(i,j);
cell=sheet->querySubObject("Cells(int,int)",i+2,j+1);
cell->setProperty("Value",item->text());
}
}
//保存工作簿
workbook->dynamicCall("SaveAs(QString)",fileName);
//关闭工作簿、结束进程
workbook->dynamicCall("Close()");
myExcell->dynamicCall("Quit()");
QMessageBox::information(this,"信息","保存成功");
}
void MainWindow::on_pushButton_insert_clicked()
{
//添加行
int currentRow=ui->tableWidget->currentRow();
ui->tableWidget->insertRow(currentRow+1);
}
void MainWindow::on_pushButton_delete_clicked()
{
//删除行
int curentRow=ui->tableWidget->currentRow();
ui->tableWidget->removeRow(curentRow);
}
//将B,L由qstring类型转换为double类型
double B=QString(textB).toDouble();
double L=QString(textL).toDouble();
//将结果x,y转换为qstring类型
QString itemx=QString::number(x,'f',4);
QString itemy=QString::number(y,'f',4);