基于Qt制作的串口调试助手控制机械臂

  • Post author:
  • Post category:其他



最近在准备互联网+比赛,写了一款串口调试助手用于机械臂的控制


找了大量资料,特别感谢微信的搜一搜,好多资料是那里面找到的,时间紧任务重,所以在UI界面和部分显示功能没有完善。。。

  1. 由于机械臂是用G代码控制的,所有具体的控制基本上是发送G代码的数控指令,关于G代码我也不是特别了解,在课间抽空稍微写了这么一个小软件,花了大概有一周的时间
  2. 机械臂的话是一个三轴的,大概就是这个样子
    在这里插入图片描述

    下面这个是软件的界面,也可以用作平时其他单片机之类的串口打印

    数据位默认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;
}



版权声明:本文为qq_50322135原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。