最近在准备互联网+比赛,写了一款串口调试助手用于机械臂的控制
找了大量资料,特别感谢微信的搜一搜,好多资料是那里面找到的,时间紧任务重,所以在UI界面和部分显示功能没有完善。。。
- 由于机械臂是用G代码控制的,所有具体的控制基本上是发送G代码的数控指令,关于G代码我也不是特别了解,在课间抽空稍微写了这么一个小软件,花了大概有一周的时间
-
机械臂的话是一个三轴的,大概就是这个样子
下面这个是软件的界面,也可以用作平时其他单片机之类的串口打印
数据位默认8位,停止位默认1位,校验位无
下面这张图这个区域一般用过串口调试助手的都应该知道,所以就不详解
下面的是机械臂控制区域,其代码指令为:
设置坐标原点:G92 X0 Y0 Z0 A0 B0
抓取:爪子打开:M3 S90 //(舵机 180°)
放下:爪子闭合:M3 S50 //(舵机 50°)
S 后面的参数 S1~S90 对应舵机角度 0~180°
上:G90 G1 X0 Y-10 Z0 F3000
//G90绝对定位指令,G1设置为指定运动速度移动到相关坐标,F3000则为3000的速度去运动,XYZ后面跟着参数则为相关坐标,向上移动则Y后面的参数向下减,我这里软件里面设定为减10
下:Y后面的参数依次加10
左:X后面的参数依次加10
右:X后面的参数依次减10
前:Z后面的参数依次减10
后:Z后面的参数依次加10
复位:直接设置原点坐标指令,为G90 G1 X0 Y0 Z0 F3000
点击“设置按钮控制区的参数”界面为
下面的是10个可以自定义的机械臂的动作按钮
打开之后大概是下面这个样子的
1、可以设置这个自定义动作的按名称,还有语音配对词, 2、因为我在这个软件中加了一个语音识别的功能,就下面这张图所示,
3、当你识别出的文字与上方按钮所自定义的语音配对词相等时,然后点击一下执行就会执行上面的用户自定义的G代码设置的相关指令,
4、上面还有一个文件保存的名称,会将上面这一页的所有信息全部保存到一个你自定义文件名的.txt文件中,后面再次打开这个软件的时候就会直接从.txt文件中设置进去
所有相关代码:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "auddio.h"
#include "qspeech.h"
#include <windows.h>
#include <QProcess>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
#include "dialog.h"
#include "dialog2.h"
#include <QButtonGroup>
#include <QThread>
#include <QTimer>
struct fileContentSave{
QString fileName;
QString pubName;
QString rouse;
QString filePath;//文件路径
};
struct GetPubSet{
QString P1_zhua;//抓取
QString P2_fang;//放下
QString P3_shang;//上移
QString P4_xia;//下移
QString P5_zuo;//左移
QString P6_you;//右移
QString P7_qian;//前移
QString P8_hou;//后移
};
class Dialog;
class Dialog2;
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
Dialog *m_signal;
Dialog2 *setPubParameter;
private slots:
void on_puB_voice_pressed();
void on_puB_voice_released();
void on_puB_clear_clicked();
void on_puB_confirm_clicked();
void on_puB_OpenPort_clicked();
void on_sendBut_clicked();
void on_SerialPort_readyRead();
void on_clearAcceptBut_clicked();
void on_clearSendBut_clicked();
void on_instrctionSet1_clicked();
void on_instrctionSet2_clicked();
void on_instrctionSet3_clicked();
void on_instrctionSet4_clicked();
void on_instrctionSe5_clicked();
void on_instrctionSet6_clicked();
void on_instrctionSet7_clicked();
void on_instrctionSet8_clicked();
void on_instrctionSet9_clicked();
void on_instrctionSet10_clicked();
void setPubName(QString name,int num);//按键名称设置
void root_array();
void root_array_2();
void execute(const fileContentSave *file_data);
void showValidPort();
void on_pushButton_11_clicked();
void on_pushButton_4_clicked();
void on_pushButton_6_clicked();
void on_pushButton_5_clicked();
void on_pushButton_7_clicked();
void on_pushButton_8_clicked();
void direction_send(QString);
void on_pushButton_9_clicked();
void on_pushButton_10_clicked();
void on_pushButton_12_clicked();
void on_pushButton_13_clicked();
void G_code_show(QString data);//G代码发送状态显示
void on_pushButton_14_clicked();
void on_pushButton_15_clicked();
void getPubparamRefresh(QString);//用于接收按钮控制区设置成功的数据
void voice_execute();//查询语音配对词
public slots:
bool eventFilter(QObject *, QEvent *);//刷新新的串口
void receiveData(QString data);//检测有没有改变按钮名称的信号发送过来
signals:
void buttonClicked(fileContentSave *);
signals:
void sendPubparam(GetPubSet *);
private:
Ui::MainWindow *ui;
auddio *m_audio;
QSerialPort *serialPort;//串口相关
bool PortOpenSign = false;//串口打开标志
QButtonGroup *my_bt;//按钮组
QTimer *timer;
int windsign;//用于记录当前是哪个按键按下
QStringList serialNamePort;
int Gx = 0,Gy = 0,Gz = 0;
fileContentSave file_Content[10];
GetPubSet Pub_Set_save;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
static int struct_sign;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
struct_sign = 0;
//语音按键相关===================================
ui->setupUi(this);
ui->puB_voice->setText("按住说话");
//串口按键相关===================================
this->setWindowTitle("机械臂语音控制系统 V2.62");
//创建一个结构体,用于按键控制的参数设置
setPubParameter = new Dialog2;
connect(this,SIGNAL(sendPubparam(GetPubSet *)),setPubParameter,SLOT(getPubparam(GetPubSet *)));
connect(setPubParameter,SIGNAL(sendPubparamrefresh(QString)),this,SLOT(getPubparamRefresh(QString)));//用于接收数据刷新
//创建一个新的窗口,并建立信号连接==================
m_signal = new Dialog;
connect(m_signal,SIGNAL(sendData(QString)),this,SLOT(receiveData(QString)));
//建一个信号发送数据到子窗口=======================发送按键数组序号
connect(this,SIGNAL(buttonClicked(fileContentSave *)),m_signal,SLOT(get_bt(fileContentSave *)));
// 创建一个串口对象==============================
serialPort = new QSerialPort(this);
/* 搜索所有可用串口 */
timer = new QTimer;
foreach (const QSerialPortInfo &inf0, QSerialPortInfo::availablePorts()) {
serialNamePort<<inf0.portName();
}
ui->com_Baud->addItems(serialNamePort);//将端口设置到列表按键中
PortOpenSign = false;//标志设置为0,关闭状态
if(serialPort->open(QIODevice::ReadWrite)){
serialPort->setDataTerminalReady(false);
}
connect(serialPort,SIGNAL(readyRead()),this,SLOT(on_SerialPort_readyRead()));//连接信号和槽
connect(timer,&QTimer::timeout,this,&MainWindow::showValidPort);//实时更新端口号
timer->start(1000);
ui->com_Baud->installEventFilter(this);
//遍历文件读取每一行的数据=======================
root_array();
//读取控制按键保存的数据
root_array_2();
}
void MainWindow::setPubName(QString name,int num)//按键名称设置
{
if(num == 0)
ui->instrctionSet1->setText(name);
if(num == 1)
ui->instrctionSet2->setText(name);
if(num == 2)
ui->instrctionSet3->setText(name);
if(num == 3)
ui->instrctionSet4->setText(name);
if(num == 4)
ui->instrctionSe5->setText(name);
if(num == 5)
ui->instrctionSet6->setText(name);
if(num == 6)
ui->instrctionSet7->setText(name);
if(num == 7)
ui->instrctionSet8->setText(name);
if(num == 8)
ui->instrctionSet9->setText(name);
if(num == 9)
ui->instrctionSet10->setText(name);
}
MainWindow::~MainWindow()
{
serialPort->close();
delete setPubParameter;
delete timer;
delete m_audio;
delete m_signal;
delete serialPort;
delete ui;
}
void MainWindow::root_array()
{
QString currentPath;
QDir dir;
dir=dir.currentPath()+"/Lib";//获取当前文件路径类似于 ./ 操作
dir.setFilter(QDir::NoDotAndDotDot | QDir::AllEntries);//过滤去除文件夹下的.目录与..目录
QStringList fileEntryList = dir.entryList();//获取dir目录下的所有条目
QFile file;
QString line;
QTextStream in(&file); //用文件构造流
int read_file_sign;
QStringList list;
for(auto fileName : fileEntryList)
{
read_file_sign = 0;
currentPath = dir.currentPath()+"/Lib";
if(fileName.endsWith(".txt"))//文件名以.txt结尾
{
file_Content[struct_sign].fileName = fileName;
list = file_Content[struct_sign].fileName.split(".");
file_Content[struct_sign].fileName = list[0];
qDebug() << "文件遍历:" << file_Content[struct_sign].fileName;
currentPath = dir.currentPath() + "/Lib/"+ fileName;//设置文件路径
//qDebug() << currentPath;
file_Content[struct_sign].filePath = currentPath;//将文件路径保存于结构体数组当中,便于后续遍历G_code内容
file.setFileName(currentPath);//设置文件名称所在的路径
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
line = in.readLine();//读取一行放到字符串里
//qDebug() << line;
file_Content[struct_sign].pubName = line;//按键名保存
setPubName(line,struct_sign);//设置按键名称
while(!line.isNull())//字符串有内容
{
line=in.readLine();//循环读取下行
if(read_file_sign == 0){
read_file_sign = 1;
file_Content[struct_sign].rouse = line;//唤醒词保存
}
//qDebug() << line;
}
struct_sign++;
}
file.close();
}
}
}
void MainWindow::root_array_2()
{
QString currentPath;
QDir dir;
currentPath=dir.currentPath() + "/GetPub" + "/1.txt";//获取当前文件路径类似于 ./ 操作
QFile file(currentPath);
QByteArray recvData;
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream in(&file); //用文件构造流
Pub_Set_save.P1_zhua = in.readLine();
// qDebug() << "1:" << Pub_Set_save->P1_zhua;
Pub_Set_save.P2_fang = in.readLine();
// qDebug() << "2:" << Pub_Set_save->P2_fang;
Pub_Set_save.P3_shang = in.readLine();
// qDebug() << "3:" << Pub_Set_save->P3_shang;
Pub_Set_save.P4_xia = in.readLine();
// qDebug() << "4:" << Pub_Set_save->P4_xia;
Pub_Set_save.P5_zuo = in.readLine();
// qDebug() << "5:" << Pub_Set_save->P5_zuo;
Pub_Set_save.P6_you = in.readLine();
// qDebug() << "6:" << Pub_Set_save->P6_you;
Pub_Set_save.P7_qian = in.readLine();
// qDebug() << "7:" << Pub_Set_save->P7_qian;
Pub_Set_save.P8_hou = in.readLine();
// qDebug() << "8:" << Pub_Set_save->P8_hou;
}
file.close();
}
void MainWindow::on_puB_voice_pressed()//录音按键按下时
{
ui->puB_voice->setText("松开识别");
QString currentPath;
QDir dir;
currentPath=dir.currentPath() + "/audio" + "/1.pcm";//获取当前文件路径类似于 ./ 操作
m_audio = new auddio;
m_audio->startAudio(currentPath);
}
void MainWindow::on_puB_voice_released()//录音按键松开
{
//停止录音
m_audio->stopAudio();
ui->puB_voice->setText("开始识别");
QString currentPath;
QDir dir;
currentPath=dir.currentPath()+"/audio";//获取当前文件路径类似于 ./ 操作
if(!dir.exists(currentPath))//检查当前文件路径是否存在,不存在就创建
{
dir.mkdir(currentPath);
}
currentPath = currentPath+"/1.pcm";
//开始识别
Qspeech m_seepch;
QString text = m_seepch.speechIdentify(currentPath);
qDebug() << text;
ui->textEdit->setText(text);
ui->puB_voice->setText("按住说话");
voice_execute();
}
void MainWindow::on_puB_clear_clicked()//语音文本清空
{
ui->textEdit->clear();
}
void MainWindow::execute(const fileContentSave *file_data)
{
QFile file(file_data->filePath);
QByteArray recvData;
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QString line;
QTextStream in(&file); //用文件构造流
line = in.readLine();//读取一行放到字符串里,前三的数据为文件名、语音定义词、按键名,无用
line = in.readLine();//
line = in.readLine();//
//qDebug() << line;
while(!line.isNull())//字符串有内容
{
line=in.readLine();//循环读取下行
G_code_show(line);//G代码发送状态显示
//qDebug() << "G代码指令为:" << line;
// 先转换为标准c++string,再转换char*字符串指针
serialPort->write((line.toStdString()+"\n").c_str());//发送到机器中
}
}
file.close();
}
void MainWindow::voice_execute()//查询语音配对词
{
QString pair_audio = ui->textEdit->toPlainText();
QStringList list = pair_audio.split("。");
//qDebug() << list[0];//已去掉“ 。”
int i;
for(i = 0; i < 10; i++){
if(file_Content[i].rouse == list[0]){//查询到语音配对词相等
execute(&file_Content[i]);
break;
}
}
}
void MainWindow::on_puB_confirm_clicked()//执行
{
voice_execute();
}
void MainWindow::on_puB_OpenPort_clicked()
{
if(PortOpenSign==false){//当前为关闭状态,下方执行打开操作
/* 串口设置 */
serialPort->setPortName(ui->com_Baud->currentText());
serialPort->setBaudRate(ui->com_Port->currentText().toInt());
serialPort->setDataBits(QSerialPort::Data8);//数据位
serialPort->setStopBits(QSerialPort::OneStop);//停止位
serialPort->setParity(QSerialPort::NoParity);//校验位
/* 打开串口提示框 */
if (true == serialPort->open(QIODevice::ReadWrite)){
//QMessageBox::information(this, "提示", "串口打开成功");
PortOpenSign = true;
ui->puB_OpenPort->setText("关闭串口");
ui->com_Baud->setEnabled(false);//打开之后波特率不可更改
ui->com_Port->setEnabled(false);//打开之后端口号不可更改
}else{
QMessageBox::critical(this, "提示", "串口打开失败");
PortOpenSign = false;
}
}else{//当前为打开状态,执行关闭操作
ui->puB_OpenPort->setText("打开串口"); //显示打开串口
serialPort->close(); //关闭串口
ui->com_Baud->setEnabled(true);//打开之后波特率不可更改
ui->com_Port->setEnabled(true);//打开之后端口号不可更改
PortOpenSign = false;
}
}
void MainWindow::on_sendBut_clicked()//发送按钮
{
if(PortOpenSign == true){
// 先转换为标准c++string,再转换char*字符串指针
serialPort->write((ui->textSend->toPlainText().toStdString()+"\n").c_str());
G_code_show(ui->textSend->toPlainText());
}
}
void MainWindow::on_SerialPort_readyRead()//串口接收区槽函数
{
if(PortOpenSign == true){
QByteArray recvData = serialPort->readAll();
//ui->textAccept->setPlainText(QString(recvData));//覆盖方式
qDebug() << "接收数据为:" << QString(recvData);
ui->textAccept->append(QString(recvData));//追加方式
}
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
QStringList serialNamePort;
if(event->type() == QEvent::MouseButtonPress)
{
if(obj == ui->com_Baud)
{
//处理鼠标点击事件
QComboBox * combobox = qobject_cast<QComboBox *>(obj);
combobox->clear();
/* 搜索所有可用串口 */
foreach (const QSerialPortInfo &inf0, QSerialPortInfo::availablePorts()) {
serialNamePort<<inf0.portName();
}
ui->com_Baud->addItems(serialNamePort);
}
}
return QWidget::eventFilter(obj, event);
}
void MainWindow::showValidPort()//检测串口是否被拔出
{
QStringList newSerialNamePort;
QString currentCOM = "";
/* 搜索所有可用串口 */
foreach (const QSerialPortInfo &inf0, QSerialPortInfo::availablePorts()) {
newSerialNamePort<<inf0.portName();
}
if(newSerialNamePort.size() != serialNamePort.size()){//更新串口
serialNamePort = newSerialNamePort;
ui->com_Baud->clear();
ui->com_Baud->addItems(serialNamePort);
}
if(currentCOM == ui->com_Baud->currentText()){//串口突然断开连接了
ui->puB_OpenPort->setText("打开串口"); //显示打开串口
serialPort->close(); //关闭串口
ui->com_Baud->setEnabled(true);//打开之后波特率不可更改
ui->com_Port->setEnabled(true);//打开之后端口号不可更改
PortOpenSign = false;
//qDebug() << "串口已拔出";
//QMessageBox::critical(this, "提示", "串口已拔出");
}
}
void MainWindow::on_clearAcceptBut_clicked()//清空接收区
{
ui->textAccept->clear();
}
void MainWindow::on_clearSendBut_clicked()//清空发送区
{
ui->textSend->clear();
}
void MainWindow::receiveData(QString data)//信号函数,接收改变按钮名称信号
{
int i;
qDebug() << "==================="<<data;
for(i=0;i<10;i++){
file_Content[i].fileName.clear();//清空该结构体内数据的内容
file_Content[i].filePath.clear();
file_Content[i].pubName.clear();
file_Content[i].rouse.clear();
}
ui->instrctionSet1->setText("");
ui->instrctionSet2->setText("");
ui->instrctionSet3->setText("");
ui->instrctionSet4->setText("");
ui->instrctionSe5->setText("");
ui->instrctionSet6->setText("");
ui->instrctionSet7->setText("");
ui->instrctionSet8->setText("");
ui->instrctionSet9->setText("");
ui->instrctionSet10->setText("");
struct_sign = 0;
root_array();
}
void MainWindow::G_code_show(QString data)//G代码发送状态显示
{
ui->textAccept_2->append(data);//追加方式
}
void MainWindow::on_instrctionSet1_clicked()//按键进入新界面
{
windsign = 1;
emit buttonClicked(&file_Content[0]);
m_signal->show();
}
void MainWindow::on_instrctionSet2_clicked()
{
windsign = 2;
emit buttonClicked(&file_Content[1]);
m_signal->show();
}
void MainWindow::on_instrctionSet3_clicked()
{
windsign = 3;
emit buttonClicked(&file_Content[2]);
m_signal->show();
}
void MainWindow::on_instrctionSet4_clicked()
{
windsign = 4;
emit buttonClicked(&file_Content[3]);
m_signal->show();
}
void MainWindow::on_instrctionSe5_clicked()
{
windsign = 5;
emit buttonClicked(&file_Content[4]);
m_signal->show();
}
void MainWindow::on_instrctionSet6_clicked()
{
windsign = 6;
emit buttonClicked(&file_Content[5]);
m_signal->show();
}
void MainWindow::on_instrctionSet7_clicked()
{
windsign = 7;
emit buttonClicked(&file_Content[6]);
m_signal->show();
}
void MainWindow::on_instrctionSet8_clicked()
{
windsign = 8;
emit buttonClicked(&file_Content[7]);
m_signal->show();
}
void MainWindow::on_instrctionSet9_clicked()
{
windsign = 9;
emit buttonClicked(&file_Content[8]);
m_signal->show();
}
void MainWindow::on_instrctionSet10_clicked()
{
windsign = 10;
emit buttonClicked(&file_Content[9]);
m_signal->show();
}
void MainWindow::direction_send(QString data)//方向按键控制 发送G_code指令
{
serialPort->write(data.toStdString().c_str());//发送到机器中
G_code_show(data);
}
void MainWindow::on_pushButton_11_clicked()//设置当前位置为原点
{
Gx = 0;
Gy = 0;
Gz = 0;
QString setOrigin = "G92 X00 Y00 Z00\n";
// 先转换为标准c++string,再转换char*字符串指针
serialPort->write(setOrigin.toStdString().c_str());//发送到机器中
G_code_show(setOrigin);
}
void MainWindow::on_pushButton_4_clicked()//上,点击状态
{
QString Gstring_send = Pub_Set_save.P3_shang+"\n";
direction_send(Gstring_send);
}
void MainWindow::on_pushButton_7_clicked()//下,点击状态
{
QString Gstring_send = Pub_Set_save.P4_xia+"\n";
direction_send(Gstring_send);
}
void MainWindow::on_pushButton_6_clicked()//左,点击状态
{
QString Gstring_send = Pub_Set_save.P5_zuo+"\n";
direction_send(Gstring_send);
}
void MainWindow::on_pushButton_5_clicked()//右,点击状态
{
QString Gstring_send = Pub_Set_save.P6_you+"\n";
direction_send(Gstring_send);
}
void MainWindow::on_pushButton_9_clicked()//前
{
QString Gstring_send = Pub_Set_save.P7_qian+"\n";
direction_send(Gstring_send);
}
void MainWindow::on_pushButton_10_clicked()//后
{
QString Gstring_send = Pub_Set_save.P8_hou+"\n";
direction_send(Gstring_send);
}
void MainWindow::on_pushButton_12_clicked()//爪子张开 M3 S90
{
QString Gstring_send = Pub_Set_save.P1_zhua+"\n";
direction_send(Gstring_send);
}
void MainWindow::on_pushButton_13_clicked()//爪子闭合
{
QString Gstring_send = Pub_Set_save.P2_fang+"\n";
direction_send(Gstring_send);
}
void MainWindow::on_pushButton_8_clicked()//复位按键
{
Gx = 0;
Gy = 0;
Gz = 0;
QString Gstring_send = "G90 X0 Y0 Z0\n";
serialPort->write(Gstring_send.toStdString().c_str());//发送到机器中
G_code_show(Gstring_send);
}
void MainWindow::on_pushButton_14_clicked()
{
ui->textAccept_2->clear();
}
void MainWindow::on_pushButton_15_clicked()//跳转到按钮参数设置界面
{
emit sendPubparam(&Pub_Set_save);
setPubParameter->show();
}
void MainWindow::getPubparamRefresh(QString data)//接收按键控制区参数设置成功发送过来的消息
{
if(data == "SetOk")
{
root_array_2();
}
}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include "mainwindow.h"
#include <QDir>
namespace Ui {
class Dialog;
}
struct fileContentSave;
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog();
signals:
void sendData(QString);
private slots:
void on_pushButton_2_clicked();
void get_bt(fileContentSave *data);//检测有没有改变按钮名称的信号发送过来
void on_pushButton_clicked();
private:
Ui::Dialog *ui;
fileContentSave *present_save;
int pubsign;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_pushButton_2_clicked()
{
if(ui->lineEdit->text().isEmpty()){//判断按键名称是否为空
QMessageBox::critical(this, "提示", "未输入按键名");
return;
}
if(ui->textEdit_2->document()->isEmpty()){//判断语配对词是否为空
QMessageBox::critical(this, "提示", "未输入配对词");
return;
}
if(ui->textEdit->document()->isEmpty()){//判断G_code指令框是否为空
QMessageBox::critical(this, "提示", "未输入G_code指令");
return;
}
if(ui->lineEdit_2->text().isEmpty()){//判断所要保存的文件名是否为空
QMessageBox::critical(this, "提示", "未输入文件名");
return;
}
QString currentPath;
QDir dir;
currentPath=dir.currentPath()+"/Lib";//获取当前文件路径类似于 ./ 操作
//qDebug() << "当前路径为:" << currentPath;
if(!dir.exists(currentPath))//检查当前文件路径是否存在,不存在就创建
{
dir.mkdir(currentPath);
qDebug()<<"文件夹创建成功";
}
currentPath = currentPath + "/" + ui->lineEdit_2->text() + ".txt";
QFile file(currentPath);
if(!file.open(QIODevice::WriteOnly | QIODevice::Text))//WriteOnly以只写的方式打开,若不存在则创建该文件
{
QMessageBox::warning(this,"sdf","can't open",QMessageBox::Yes);
}
QTextStream in(&file);
in<<ui->lineEdit->text()<<"\n";//如果写多行,同上循环即可 按键名
in<<ui->textEdit_2->toPlainText() <<"\n";//textEdit框按行写入 配对词
in<<ui->lineEdit_2->text()<<"\n";// 文件名
in<<ui->textEdit->toPlainText();
file.close();
//将按键名名称发送给主界面
emit sendData(ui->lineEdit->text());
close();
}
void Dialog::get_bt(fileContentSave * data)//检测有没有改变按钮名称的信号发送过来
{
present_save = data;
ui->textEdit->clear();//清空该文本框以防止有内容滞留
qDebug() << "path is" << data->filePath;
QFile file(data->filePath);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QString line;
QTextStream in(&file); //用文件构造流
line = in.readLine();//读取一行放到字符串里,前三的数据为文件名、语音定义词、按键名,无用
line = in.readLine();//
line = in.readLine();//
//qDebug() << line;
while(!line.isNull())//字符串有内容
{
line=in.readLine();//循环读取下行
ui->textEdit->append(line);
}
}
file.close();
//将结构体的内容设置到各控件当中
ui->lineEdit_2->setText(data->fileName);
ui->lineEdit->setText(data->pubName);
ui->textEdit_2->setText(data->rouse);
}
void Dialog::on_pushButton_clicked()
{
if(!QDir().exists(present_save->filePath)){//判断该路径是否存在
QMessageBox::critical(this, "提示", "查询不到该路径");
}
QFileInfo FileInfo(present_save->filePath);
if (FileInfo.isFile())//如果是文件,删除文件
QFile::remove(present_save->filePath);
present_save->fileName.clear();//清空该结构体内数据的内容
present_save->filePath.clear();
present_save->pubName.clear();
present_save->rouse.clear();
emit sendData("clear");
close();
}
dialog2.h
#ifndef DIALOG2_H
#define DIALOG2_H
#include <QDialog>
#include <QDebug>
#include <QFile>
#include <QMessageBox>
#include <QDir>
#include "mainwindow.h"
namespace Ui {
class Dialog2;
}
struct GetPubSet;
class Dialog2 : public QDialog
{
Q_OBJECT
public:
explicit Dialog2(QWidget *parent = nullptr);
~Dialog2();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void getPubparam(GetPubSet *);
signals:
void sendPubparamrefresh(QString);
private:
Ui::Dialog2 *ui;
};
#endif // DIALOG2_H
dialog2.cpp
#include "dialog2.h"
#include "ui_dialog2.h"
Dialog2::Dialog2(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog2)
{
ui->setupUi(this);
}
Dialog2::~Dialog2()
{
delete ui;
}
void Dialog2::on_pushButton_clicked()
{
if(ui->lineEdit->text().isEmpty()){//判断按键名称是否为空
QMessageBox::critical(this, "提示", "未设置爪子打开指令");
return;
}
if(ui->lineEdit_2->text().isEmpty()){//判断按键名称是否为空
QMessageBox::critical(this, "提示", "未设置爪子闭合指令");
return;
}
if(ui->lineEdit_3->text().isEmpty()){//判断按键名称是否为空
QMessageBox::critical(this, "提示", "未设置向上移动指令");
return;
}
if(ui->lineEdit_4->text().isEmpty()){//判断按键名称是否为空
QMessageBox::critical(this, "提示", "未设置向下移动指令");
return;
}
if(ui->lineEdit_5->text().isEmpty()){//判断按键名称是否为空
QMessageBox::critical(this, "提示", "未设置向左移动指令");
return;
}
if(ui->lineEdit_6->text().isEmpty()){//判断按键名称是否为空
QMessageBox::critical(this, "提示", "未设置向右移动指令");
return;
}
if(ui->lineEdit_7->text().isEmpty()){//判断按键名称是否为空
QMessageBox::critical(this, "提示", "未设置向前移动指令");
return;
}
if(ui->lineEdit_8->text().isEmpty()){//判断按键名称是否为空
QMessageBox::critical(this, "提示", "未设置向后移动指令");
return;
}
QString currentPath;
QDir dir;
currentPath=dir.currentPath()+"/GetPub";//获取当前文件路径类似于 ./ 操作
//qDebug() << "当前路径为:" << currentPath;
if(!dir.exists(currentPath))//检查当前文件路径是否存在,不存在就创建
{
dir.mkdir(currentPath);
qDebug()<<"文件夹创建成功";
}
currentPath = currentPath + "/1.txt";
QFile file(currentPath);
if(!file.open(QIODevice::WriteOnly | QIODevice::Text))//WriteOnly以只写的方式打开,若不存在则创建该文件
{
QMessageBox::warning(this,"sdf","can't open",QMessageBox::Yes);
}
QTextStream in(&file);
in<<ui->lineEdit->text()<<"\n";
in<<ui->lineEdit_2->text() <<"\n";
in<<ui->lineEdit_3->text()<<"\n";
in<<ui->lineEdit_4->text()<<"\n";
in<<ui->lineEdit_5->text()<<"\n";
in<<ui->lineEdit_6->text()<<"\n";
in<<ui->lineEdit_7->text()<<"\n";
in<<ui->lineEdit_8->text()<<"\n";
file.close();
//将按键名名称发送给主界面
emit sendPubparamrefresh("SetOk");
close();
}
void Dialog2::on_pushButton_2_clicked()
{
ui->lineEdit->clear();
ui->lineEdit_2->clear();
ui->lineEdit_3->clear();
ui->lineEdit_4->clear();
ui->lineEdit_5->clear();
ui->lineEdit_6->clear();
ui->lineEdit_7->clear();
ui->lineEdit_8->clear();
}
void Dialog2::getPubparam(GetPubSet *data)
{
ui->lineEdit->setText(data->P1_zhua);
ui->lineEdit_2->setText(data->P2_fang);
ui->lineEdit_3->setText(data->P3_shang);
ui->lineEdit_4->setText(data->P4_xia);
ui->lineEdit_5->setText(data->P5_zuo);
ui->lineEdit_6->setText(data->P6_you);
ui->lineEdit_7->setText(data->P7_qian);
ui->lineEdit_8->setText(data->P8_hou);
}
audio.h
#ifndef AUDDIO_H
#define AUDDIO_H
#include <QObject>
#include <QAudioFormat>
#include <QAudioDeviceInfo>//获取录因设备信息
#include <QMessageBox>
#include <QAudioInput>
#include <QFile>
#include <QDebug>
class auddio : public QObject
{
Q_OBJECT
public:
explicit auddio(QObject *parent = nullptr);
void startAudio(QString filename);//开始录音
void stopAudio();//结束录音
signals:
public slots:
private:
QAudioInput *m_audio;
QFile *m_file;
};
#endif // AUDDIO_H
audio.cpp
#include "auddio.h"
auddio::auddio(QObject *parent) : QObject(parent)
{
}
void auddio::startAudio(QString filename)
{
//判断电脑是否有录音设备
QAudioDeviceInfo device = QAudioDeviceInfo::defaultInputDevice();
if(device.isNull()){//录音设备不存在
QMessageBox::warning(NULL,"QAudioDeviceInfo","录音设备不存在");
}else{
QAudioFormat m_format;
//设置采样频率
m_format.setSampleRate(16000);
//设置通道
m_format.setChannelCount(1);
//设置位深
m_format.setSampleSize(16);
//设置编码
m_format.setCodec("audio/pcm");
//判断设备是否支持该格式
if(!device.isFormatSupported(m_format)){
//qDebug() << "audio format open error!" << endl;
m_format = device.nearestFormat(m_format);
}
//打开文件
m_file = new QFile;
m_file->setFileName(filename);
m_file->open(QIODevice::WriteOnly);
//创建录音对象
m_audio = new QAudioInput(m_format,this);
m_audio->start(m_file);
}
}
void auddio::stopAudio()
{
//停止录音
m_audio->stop();
//关闭文件
m_file->close();
//删除文件对向
delete m_file;
m_file = NULL;
}
http.h
#ifndef HTTP_H
#define HTTP_H
#include <QObject>
#include <QMap>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QEventLoop>
#include <QDebug>
class Http : public QObject
{
Q_OBJECT
public:
explicit Http(QObject *parent = nullptr);
bool post_sync(QString Url,QMap<QString,QString>header,QByteArray requestData,QByteArray &replaydata);
signals:
};
#endif // HTTP_H
http.cpp
#include "http.h"
Http::Http(QObject *parent) : QObject(parent)
{
}
bool Http::post_sync(QString Url, QMap<QString, QString> header, QByteArray requestData, QByteArray &replaydata)
{
//发送请求的对象
QNetworkAccessManager manager;
//请求对象
QNetworkRequest request;
request.setUrl(Url);
QMapIterator<QString,QString> it(header);//迭代器
while(it.hasNext()){
it.next();
request.setRawHeader(it.key().toLatin1(),it.value().toLatin1());
}
QNetworkReply *reply= manager.post(request,requestData);//发送
QEventLoop l;
//一旦服务器返回,reply会发出信号
connect(reply,&QNetworkReply::finished,&l,&QEventLoop::quit);
l.exec();//死循环,replay发出信号,结束循环
if(reply!=nullptr && reply->error() == QNetworkReply::NoError){
replaydata = reply->readAll();//读取服务器返回出来的数据
//qDebug() << replaydata;
return true;
}else{
qDebug() << "请求失败";
return false;
}
}
qspeech.h
#ifndef QSPEECH_H
#define QSPEECH_H
#include <QObject>
#include "http.h"
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
#include <QHostInfo>
#include <QFile>
#include <QMessageBox>
//获取access_token相关
const QString baiduTokenUrl = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%1&client_secret=%2&";
const QString client_id = "xxxxxxxxxx";//你自己的百度语音识别API接口id(Http请求方式)
const QString client_secret = "xxxxxxxxxxxxx";//你自己的百度语音识别的API接口密钥(Http请求方式)
//语音识别相关
const QString baiduSpeechUrl = "http://vop.baidu.com/server_api?dev_pid=1537&cuid=%1&token=%2";
class Qspeech : public QObject
{
Q_OBJECT
public:
explicit Qspeech(QObject *parent = nullptr);
QString speechIdentify(QString filenamme);
QString getJsonValue(QByteArray ba,QString key);
signals:
};
#endif // QSPEECH_H
qspeech.cpp
#include "qspeech.h"
Qspeech::Qspeech(QObject *parent) : QObject(parent)
{
}
QString Qspeech::speechIdentify(QString filenamme)
{
QString accessToken;
//获取access_token
QString tokenUrl = QString(baiduTokenUrl).arg(client_id).arg(client_secret);
QMap<QString,QString> header;
header.insert(QString("Content-Type"),QString("audio/pcm;rate=16000"));
QByteArray requestData;//发送内容
QByteArray replayData;//服务器返回的内容
Http m_http;
bool result = m_http.post_sync(tokenUrl,header,requestData,replayData);
if(result){
QString key = "access_token";
accessToken = getJsonValue(replayData,key);
qDebug() << accessToken;
}else{
}
//识别语音
QString speechUrl = QString(baiduSpeechUrl).arg(QHostInfo::localHostName()).arg(accessToken);
//把文件转换成QByteArray
QFile file;
file.setFileName(filenamme);
file.open(QIODevice::ReadOnly);
requestData = file.readAll();
file.close();
replayData.clear();
//再次发起请求
result = m_http.post_sync(speechUrl,header,requestData,replayData);
if(result){
QString key = "result";
QString text = getJsonValue(replayData,key);
//qDebug() <<"1111111:"<< replayData;
//qDebug() <<"<><><><><:"<< text;
return text;
}else{
QMessageBox::warning(NULL,"识别提示","识别失败");
}
return "";
}
QString Qspeech::getJsonValue(QByteArray ba, QString key)
{
QJsonParseError parseError;
QJsonDocument jsonDocument = QJsonDocument::fromJson(ba,&parseError);
if(parseError.error == QJsonParseError::NoError){//判断是否解析正确
if(jsonDocument.isObject()){
//jsonDocument转换成json对象
QJsonObject jsonObj = jsonDocument.object();
if(jsonObj.contains(key)){
QJsonValue jsonVal = jsonObj.value(key);
if(jsonVal.isString()){//字符串
return jsonVal.toString();
}else if(jsonVal.isArray()){//数组
QJsonArray arr = jsonVal.toArray();//转换成JsonArray
QJsonValue jv = arr.at(0);//获取第一个元素
return jv.toString();
}
}
}
}
return NULL;
}