利用窗口程序实现对PSD激光接收装置进行指令接收/发送。当成功连接装置后,能够通过设置绝对零位来校正坐标,点击信息获取后能够接收装置所发来的十六进制数据,按照设计协议对数据进行拆分,剥离出有用的数据信息后在窗口显示,并能够讲这些数据写入Excel文件当中进行保存。
QT += core gui serialport axcontainer
#ifndef WIDGET_H
#define WIDGET_H
//引入串口通信的两个头文件
#include //提供访问串口的功能
#include //提供系统中存在的串口信息
#include
#include
#include
#include
#include
#include
#include
#include "QFileDialog"
#include "QAxObject"
#include "QFile"
#include
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
//选择文件槽函数
void on_BtnChooseFile_clicked();
//发送接收数据指令槽函数
void on_BtnRecive_clicked();
//连接串口槽函数
void on_BtnConnect_clicked();
//获取密码槽函数
void on_BtnKey_clicked();
//设置绝对零位槽函数
void on_BtnSetZero_clicked();
private:
Ui::Widget *ui;
// 实例化串口类
QSerialPort mSerialPort;
// 记录表格当前行
int rowNum = 1;
// 创建Excel进程
QAxObject *excel = new QAxObject(this);
// 文件创建路径
QString excel_path_1;
// 定义工作簿
QAxObject *workbooks;
QAxObject *workbook;
// 定义工作表
QAxObject *worksheets;
QAxObject *worksheet;
};
#endif // WIDGET_H
// 设置端口默认值
// 设置端口号
mSerialPort.setPortName("COM4");
// 设置波特率
mSerialPort.setBaudRate(QSerialPort::Baud9600);
// 设置校验位
mSerialPort.setParity(QSerialPort::NoParity);
// 设置数据位
mSerialPort.setDataBits(QSerialPort::Data8);
// 设置停止位
mSerialPort.setStopBits(QSerialPort::OneStop);
//用户选择文件夹路径
QFileDialog *fileDialog = new QFileDialog(this);
fileDialog->setFileMode(QFileDialog::Directory);
fileDialog->exec();
auto selectDir = fileDialog->selectedFiles();
ui->labelSetFile->setText(selectDir.at(0));
excel_path_1 = selectDir.at(0) + QString::fromLocal8Bit("/PSD激光接收装置数据接收表.xlsx"); //设置文件路径、名、格式
//如果用户选择了路径
if (selectDir.size()>0)
{
//设置Excel表格
excel->setControl("Excel.Application");//连接Excel控件
excel->dynamicCall("SetVisible (bool Visible)","false");//不显示窗体
excel->setProperty("DisplayAlerts", true);//不显示任何警告信息。如果为true那么在关闭是会出现类似“文件已修改,是否保存”的提示
workbooks = excel->querySubObject("WorkBooks");//获取工作簿集合
workbooks->dynamicCall("Add");//新建一个工作簿
workbook = excel->querySubObject("ActiveWorkBook");//获取当前工作簿
worksheets = workbook->querySubObject("Sheets");//获取工作表集合
worksheet = worksheets->querySubObject("Item(int)",1);//获取工作表集合的工作表1,即sheet1
//标题行
QAxObject *cell;
cell=worksheet->querySubObject("Cells(int,int)", 1, 1);
cell->dynamicCall("SetValue(const QString&)", QString::fromLocal8Bit("PSD激光接收装置数据接收表"));
cell->querySubObject("Font")->setProperty("Size", 11);
//合并标题行
QString cellTitle;
cellTitle.append("A1:");
cellTitle.append(QChar(4 + 'A'));
cellTitle.append(QString::number(1));
QAxObject *range = worksheet->querySubObject("Range(const QString&)", cellTitle);
range->setProperty("WrapText", true);
range->setProperty("MergeCells", true);
range->setProperty("HorizontalAlignment", -4108);//xlCenter
range->setProperty("VerticalAlignment", -4108);//xlCenter
// 定义Excel单元格
QAxObject *cellA,*cellB,*cellC,*cellD,*cellE;
int cellrow=2;
QString A="A"+QString::number(cellrow);//设置要操作的单元格,如A1
QString B="B"+QString::number(cellrow);
QString C="C"+QString::number(cellrow);
QString D="D"+QString::number(cellrow);
QString E="E"+QString::number(cellrow);
QString F="A"+QString::number(3);
//获取单元格
cellA = worksheet->querySubObject("Range(QVariant, QVariant)",A);
cellB = worksheet->querySubObject("Range(QVariant, QVariant)",B);
cellC = worksheet->querySubObject("Range(QVariant, QVariant)",C);
cellD = worksheet->querySubObject("Range(QVariant, QVariant)",D);
cellE = worksheet->querySubObject("Range(QVariant, QVariant)",E);
//向单元格中写入数据
cellA->dynamicCall("SetValue(const QVariant&)",QString::fromLocal8Bit("接收器编号"));//设置单元格的值
cellB->dynamicCall("SetValue(const QVariant&)",QString::fromLocal8Bit("数据序号"));
cellC->dynamicCall("SetValue(const QVariant&)",QString::fromLocal8Bit("X轴"));
cellD->dynamicCall("SetValue(const QVariant&)",QString::fromLocal8Bit("Y轴"));
cellE->dynamicCall("SetValue(const QVariant&)",QString::fromLocal8Bit("ψ"));
}
5.连接设备,对配置好的串口进行打开。
//判断用户是打开连接还是关闭连接
if(ui->BtnConnect->text() == QString::fromLocal8Bit("连接数据接口")){
//设置打开方式
mSerialPort.open(QSerialPort::ReadWrite);
if(true == mSerialPort.isOpen()){
ui->BtnConnect->setText(QString::fromLocal8Bit("关闭数据接口"));
ui->labelPortConnect->setText(QString::fromLocal8Bit("端口已连接"));
}else
{
qDebug() << "fail";
}
}
//发送同步信号
QByteArray buffer;
buffer.append('\xAA');
buffer.append('\x01');
buffer.append('\xBB');
mSerialPort.write(buffer);
//定义信号接收槽(用于接收PSD向计算机发来的数据)
connect(&mSerialPort,&QSerialPort::readyRead,
[=]()
{
//接收到PSD发送来的一条数据
const QByteArray info = mSerialPort.readAll().toHex();
qDebug()<<"receive info:"<<info;
//逐个拆分每一个字节进行解析
qDebug()<<QString::fromLocal8Bit("第一个字节是:")<<info[0]<<info[1]<<endl;
qDebug()<<QString::fromLocal8Bit("第二个字节是:")<<info[2]<<info[3]<<endl;
qDebug()<<QString::fromLocal8Bit("第三个字节是:")<<info[4]<<info[5]<<endl;
qDebug()<<QString::fromLocal8Bit("第四个字节是:")<<info[6]<<info[7]<<endl;
qDebug()<<QString::fromLocal8Bit("第五个字节是:")<<info[8]<<info[9]<<endl;
//写入传来的一条数据
ui->tableWidget->setItem(rowNum,1,new QTableWidgetItem(QString::fromLocal8Bit("1号编辑器")));
ui->tableWidget->setItem(rowNum,2,new QTableWidgetItem(QString::number(rowNum)));
ui->tableWidget->setItem(rowNum,3,new QTableWidgetItem(QString::fromLocal8Bit("x轴数据")));
ui->tableWidget->setItem(rowNum,4,new QTableWidgetItem(QString::fromLocal8Bit("y轴数据")));
ui->tableWidget->setItem(rowNum++,5,new QTableWidgetItem(QString::fromLocal8Bit("ψ轴数据")));
//如果数据量大于14条,需要继续追加行
if(rowNum >= 14){
ui->tableWidget->insertRow(rowNum);
}
//定义Excel单元格对象用来向Excel中添加数据
QAxObject *cellA,*cellB,*cellC,*cellD,*cellE;
int cellrow=rowNum+1;
//设置要操作的单元格,如A1
QString A="A"+QString::number(cellrow);
QString B="B"+QString::number(cellrow);
QString C="C"+QString::number(cellrow);
QString D="D"+QString::number(cellrow);
QString E="E"+QString::number(cellrow);
//获取单元格
cellA = worksheet->querySubObject("Range(QVariant, QVariant)",A);
cellB = worksheet->querySubObject("Range(QVariant, QVariant)",B);
cellC = worksheet->querySubObject("Range(QVariant, QVariant)",C);
cellD = worksheet->querySubObject("Range(QVariant, QVariant)",D);
cellE = worksheet->querySubObject("Range(QVariant, QVariant)",E);
//向单元格中写入数据
cellA->dynamicCall("SetValue(const QVariant&)",QString::fromLocal8Bit("1号编辑器"));//设置单元格的值
cellB->dynamicCall("SetValue(const QVariant&)",QString::number(rowNum-1));
cellC->dynamicCall("SetValue(const QVariant&)",QString::fromLocal8Bit("X轴"));
cellD->dynamicCall("SetValue(const QVariant&)",QString::fromLocal8Bit("Y轴"));
cellE->dynamicCall("SetValue(const QVariant&)",QString::fromLocal8Bit("ψ"));
});
if(true == mSerialPort.isOpen()){
//关闭串口连接
mSerialPort.close();
ui->BtnConnect->setText(QString::fromLocal8Bit("连接数据接口"));
ui->labelPortConnect->setText(QString::fromLocal8Bit("端口未连接"));
//关闭Excel表格
workbook->dynamicCall("SaveAs(const QString&)",QDir::toNativeSeparators(excel_path_1));//保存至filepath,注意一定要用QDir::toNativeSeparators将路径中的"/"转换为"\",不然一定保存不了。
workbook->dynamicCall("Close()");//关闭工作簿
excel->dynamicCall("Quit()");//关闭excel
delete excel;
excel=NULL;
}