一、我们在处理数据或者进行数据输入输出时有时候需要用到度数,如35.8°,有时候需要用到度分秒41°48′23.126″,而给你的数据正好相反,那么就需要进行数据转换。对于普通的度分秒(全为整数),如41°48′23″,利用Excel进行转换也是非常容易的,网上也有很多教程。但是如果含有小数或者说浮点型的数据那就比较难处理。
二、本文介绍如何利用Qt以文件的形式进行两者的互相转换,利用Qt开发环境做界面,使用C++语言实现。通过打开文件和自动保存文件的形式。效果如下:
三、数据准备:数据一般存放在Excel中,首先需要复制Excel中的数据(假设是度分秒格式的)到文本文件中(Qt直接读取Excel文件比较困难),注意命名的时候不要用中文,数据格式如下图所示:
四、打开Qt,新建项目degree,类名选择Widget,这里不需要Mainwindow。首先进行ui界面设计,效果如上图所示,按钮使用“转到槽”进行信号和槽的连接。
五、头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QDir>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
//输出函数
void out();
private:
QFile *file = new QFile;
QStringList fNames;//可以批量读取文件
QStringList list;
QString name;
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
六、cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle("度分秒与度数互转");
}
Widget::~Widget()
{
delete ui;
}
//度分秒 => 度数
void Widget::on_pushButton_clicked()
{
fNames = QFileDialog::getOpenFileNames(this,"open file",QDir::currentPath(),"Text Files (*.txt)");
if(fNames.isEmpty())
{
QMessageBox::warning(this,"Warning","File is empty!");
}
else
{
for(int i = 0; i < fNames.size(); i++)
{
file->setFileName(fNames[i]);
name = fNames[i];
bool ok = file->open(QFile::ReadOnly);//只读
if(ok)
{
QTextStream in(file);
while(!in.atEnd())
{
list.append(in.readLine());
}
for(int i = 0; i < list.size(); i++)
{
QString s1 = list.at(i);
s1 = s1.replace("°"," ");
s1 = s1.replace("′"," ");
s1 = s1.remove("″");
s1 = s1.replace("\t"," ");
QStringList s2 = s1.split(" ");
QString ssss1,ssss2;
for(int i=0;i<s2.size();i++)
{
QString s = s2.at(0);
double dd1 = s.toDouble();
QString ss =s2.at(1);
double dd2 = ss.toDouble();
QString sss =s2.at(2);
double dd3 = sss.toDouble();
double ddd = dd1 + dd2/60 + dd3/3600;
ssss1 = QString::number(ddd,'f',4);
QString st1 = s2.at(3);
double dd4 = st1.toDouble();
QString st2 =s2.at(4);
double dd5 = st2.toDouble();
QString st3 =s2.at(5);
double dd6 = st3.toDouble();
double dd = dd4 + dd5/60 + dd6/3600;
ssss2 = QString::number(dd,'f',4);
}
list[i] = ssss1 + " " + ssss2;
}
out();
file->close();//关闭文件
}
else
{
QMessageBox::information(this,"Error","File open failed!");
return;
}
}
}
}
//度数 => 度分秒
void Widget::on_pushButton_2_clicked()
{
fNames = QFileDialog::getOpenFileNames(this,"open file",QDir::currentPath(),"Text Files (*.txt)");
if(fNames.isEmpty())
{
QMessageBox::warning(this,"Warning","File is empty!");
}
else
{
for(int i = 0; i < fNames.size(); i++)
{
file->setFileName(fNames[i]);
name = fNames[i];
bool ok = file->open(QFile::ReadOnly);//只读
if(ok)
{
QTextStream in(file);
while(!in.atEnd())
{
list.append(in.readLine());
}
for(int i = 0; i < list.size(); i++)
{
QString s1 = list.at(i);
QStringList s2 = s1.split(" ");
QString str;
for(int i=0;i<s2.size();i++)
{
QString ss1 = s2.at(0);
double d1 = ss1.toDouble();
double hou = floor(d1);
double min = (d1-floor(d1))*60;
double sec = (min-floor(min))*60;
int minute = floor(min);
QString st1 = QString::number(hou) + "°" + QString("%1").arg(minute,2,10,QLatin1Char('0')) +"′" + QString::number(sec,'f',3) + "″";
QString ss2 = s2.at(1);
double d2 = ss2.toDouble();
double hou2 = floor(d2);
double min2 = (d2-floor(d2))*60;
double sec2 = (min2-floor(min2))*60;
int minute2 = floor(min2);
QString st2 = QString::number(hou2) + "°" + QString("%2").arg(minute2,2,10,QLatin1Char('0')) +"′" + QString::number(sec2,'f',3) + "″";
str = st1 + " " + st2;
}
list[i] = str;
}
out();
file->close();//关闭文件
}
else
{
QMessageBox::information(this,"Error","File open failed!");
return;
}
}
}
}
//输出函数
void Widget::out()
{
file->setFileName(name);
bool ok = file->open(QFile::WriteOnly | QIODevice::Truncate);//覆盖写入
if(ok)
{
//文件与文本流相关联
QTextStream out(file);
for(int i = 0; i < list.size(); i++)
{
out << list[i];
out << "\n";
}
list.clear();//清空列表
file->flush();
file->close();//关闭文件
QMessageBox::information(this,"提示","保存成功,请打开源文件。");
}
else
QMessageBox::warning(this,"Warning","Not Saved!");
}
七、说明:由于使用的是getOpenFileNames函数不是getOpenFileName函数,因此可以进行批量文件读取,所以在最外一层多了一个for循环用来读取所有文件的名称,中间使用replace函数讲度分秒的符号替换,这是为了防止用其他方法读数据的时候因为数据的长短造成读取失败。没有设置保存文件的按钮,所以是覆盖写入到原文本文件中。处理结果如下:
八、第二个按钮提供了相反的操作,可以将上一步骤生成的度数文件转换为度分秒格式的文件。处理结果如下:
可以看到和原始的数据在秒那里有一点不一样,这是因为精度丢失的问题。最后将得到的数据复制粘贴到Excel中即可。
九、如有问题,欢迎评论区留言,我会及时回复。如果需要打包发布的程序也可以联系博主。