QT—串口调试助手
功能描述
检测并列举系统中的可用串口
配置波特率,校验位,停止位,数据位
多文本发送
启动串口
发送数据
接收数据
界面展示
串口调试助手自动检测串口号
QList<QSerialPortInfo> serialList=QSerialPortInfo::availablePorts(); //检测串口
for(QSerialPortInfo serialInfo:serialList)
{
qDebug()<<serialInfo.portName(); //打印串口号
ui->comboBox_serialNum_2->addItem(serialInfo.portName());//把检测的串口追加到控件中
}
串口助手实现打开串口
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QSerialPort>
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_btnCloseOropenSerial_clicked();
private:
Ui::Widget *ui;
QSerialPort *serialport;
};
#endif // WIDGET_H
widget.cpp
serialport=new QSerialPort;
ui->comboBox_boautrate_2->setCurrentIndex(6);//设置默认波特率为115200
ui->comboBox_datait_2->setCurrentIndex(3);//设置默认数据位为8位
//打开串口
void Widget::on_btnCloseOropenSerial_clicked()
{
//1.选择端口号
serialport->setPortName(ui->comboBox_serialNum_2->currentText());
//2.配置波特率
serialport->setBaudRate(ui->comboBox_boautrate_2->currentText().toInt());
//3.配置数据位
serialport->setDataBits(QSerialPort::DataBits(ui->comboBox_datait_2->currentText().toUInt()));
//4.配置校验位
switch(ui->comboBox_jiaoyan_2->currentIndex())
{
case 0:
serialport->setParity(QSerialPort::NoParity);
break;
case 1:
serialport->setParity(QSerialPort::EvenParity);
break;
case 2:
serialport->setParity(QSerialPort::OddParity);
break;
case 3:
serialport->setParity(QSerialPort::SpaceParity);
break;
case 4:
serialport->setParity(QSerialPort::MarkParity);
break;
default:
serialport->setParity(QSerialPort::UnknownParity);
break;
}
//5.配置停止位
serialport->setStopBits(QSerialPort::StopBits(ui->comboBox_stopbit_2->currentText().toUInt()));
//6.流控
if(ui->comboBox_fileCon_2->currentText()=="None")
{
serialport->setFlowControl(QSerialPort::NoFlowControl);
}
//7.打开串口
if(serialport->open(QIODevice::ReadWrite))
{
qDebug()<<"serial open success!";
}
}
串口调试助手实现自发自收
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QSerialPort>
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_btnCloseOropenSerial_clicked();
void on_btnSendContext_clicked();
void on_SerialData_readyToRead();
private:
Ui::Widget *ui;
QSerialPort *serialPort;
};
#endif // WIDGET_H
widget.cpp
connect(serialPort,&QSerialPort::readyRead,this,&Widget::on_SerialData_readyToRead);
//打开串口
void Widget::on_btnCloseOropenSerial_clicked()
{
//1.选择端口号
serialPort->setPortName(ui->comboBox_serialNum_2->currentText());
//2.配置波特率
serialPort->setBaudRate(ui->comboBox_boautrate_2->currentText().toInt());
//3.配置数据位
serialPort->setDataBits(QSerialPort::DataBits(ui->comboBox_datait_2->currentText().toUInt()));
//4.配置校验位
switch(ui->comboBox_jiaoyan_2->currentIndex())
{
case 0:
serialPort->setParity(QSerialPort::NoParity);
break;
case 1:
serialPort->setParity(QSerialPort::EvenParity);
break;
case 2:
serialPort->setParity(QSerialPort::OddParity);
break;
case 3:
serialPort->setParity(QSerialPort::SpaceParity);
break;
case 4:
serialPort->setParity(QSerialPort::MarkParity);
break;
default:
serialPort->setParity(QSerialPort::UnknownParity);
break;
}
//5.配置停止位
serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_stopbit_2->currentText().toUInt()));
//6.流控
if(ui->comboBox_fileCon_2->currentText()=="None")
{
serialPort->setFlowControl(QSerialPort::NoFlowControl);
}
//7.打开串口
if(serialPort->open(QIODevice::ReadWrite))
{
qDebug()<<"serial open success!";
}
}
//发数据
void Widget::on_btnSendContext_clicked()
{
const char* sendData=ui->lineEditsendcontext->text().toStdString().c_str();
serialPort->write(sendData);
qDebug()<<"send Ok!"<<sendData;
ui->textEditRecord->append(sendData);
}
//收数据
void Widget::on_SerialData_readyToRead()
{
QString recvMessage=serialPort->readAll();
qDebug()<<"getMessage:"<<recvMessage;
ui->textEditRev->append(recvMessage);
}
串口发送状态更新
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QSerialPort>
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_btnCloseOropenSerial_clicked();
void on_btnSendContext_clicked();
void on_SerialData_readyToRead();
private:
Ui::Widget *ui;
QSerialPort *serialPort;
int writeCntTotal;
int readCntTotal;
QString sendbak;
};
#endif // WIDGET_H
widget.cpp
//发数据
void Widget::on_btnSendContext_clicked()
{
int writeCnt=0;
const char* sendData=ui->lineEditsendcontext->text().toStdString().c_str();
writeCnt=serialPort->write(sendData);
if(writeCnt==-1) //发送失败
{
ui->labelSendStaus->setText("send Error!");
}
else //发送成功
{
writeCntTotal+=writeCnt;
qDebug()<<"send Ok!"<<sendData;
ui->labelSendStaus->setText("send OK!");
ui->labelSendcnt->setNum(writeCntTotal);
if(strcmp(sendData,sendbak.toStdString().c_str())!=0)
{
ui->textEditRecord->append(sendData);
sendbak=QString(sendData) ; //保存上一次记录
}
}
}
//收数据
void Widget::on_SerialData_readyToRead()
{
QString recvMessage=serialPort->readAll();
if(recvMessage!=NULL)
{
qDebug()<<"getMessage:"<<recvMessage;
ui->textEditRev->append(recvMessage);
readCntTotal+=recvMessage.size();
ui->labelRevcnt->setNum(readCntTotal);
}
}
串口发送状态界面优化
串口打开状态的优化
方式一
void Widget::on_btnCloseOropenSerial_clicked(bool checked)
{
if(checked) //串口没打开
{
//1.选择端口号
serialPort->setPortName(ui->comboBox_serialNum_2->currentText());
//2.配置波特率
serialPort->setBaudRate(ui->comboBox_boautrate_2->currentText().toInt());
//3.配置数据位
serialPort->setDataBits(QSerialPort::DataBits(ui->comboBox_datait_2->currentText().toUInt()));
//4.配置校验位
switch(ui->comboBox_jiaoyan_2->currentIndex())
{
case 0:
serialPort->setParity(QSerialPort::NoParity);
break;
case 1:
serialPort->setParity(QSerialPort::EvenParity);
break;
case 2:
serialPort->setParity(QSerialPort::OddParity);
break;
case 3:
serialPort->setParity(QSerialPort::SpaceParity);
break;
case 4:
serialPort->setParity(QSerialPort::MarkParity);
break;
default:
serialPort->setParity(QSerialPort::UnknownParity);
break;
}
//5.配置停止位
serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_stopbit_2->currentText().toUInt()));
//6.流控
if(ui->comboBox_fileCon_2->currentText()=="None")
{
serialPort->setFlowControl(QSerialPort::NoFlowControl);
}
//7.打开串口
if(serialPort->open(QIODevice::ReadWrite)) //打开成功
{
qDebug()<<"serial open success!";
ui->comboBox_serialNum_2->setEnabled(false);
ui->comboBox_boautrate_2->setEnabled(false);
ui->comboBox_datait_2->setEnabled(false);
ui->comboBox_stopbit_2->setEnabled(false);
ui->comboBox_jiaoyan_2->setEnabled(false);
ui->comboBox_fileCon_2->setEnabled(false);
ui->btnCloseOropenSerial->setText("关闭串口");
ui->btnSendContext->setEnabled(true);
}
else
{
QMessageBox msgBox;
msgBox.setWindowTitle("打开串口错误");
msgBox.setText("打开失败,串口可能被占用!");
msgBox.exec();
}
}
else //串口打开置为没打开
{
serialPort->close();//关闭串口
ui->comboBox_serialNum_2->setEnabled(true);
ui->comboBox_boautrate_2->setEnabled(true);
ui->comboBox_datait_2->setEnabled(true);
ui->comboBox_stopbit_2->setEnabled(true);
ui->comboBox_jiaoyan_2->setEnabled(true);
ui->comboBox_fileCon_2->setEnabled(true);
ui->btnCloseOropenSerial->setText("打开串口");
ui->btnSendContext->setEnabled(false);
}
}
方式二
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QSerialPort>
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_btnCloseOropenSerial_clicked();
void on_btnSendContext_clicked();
void on_SerialData_readyToRead();
void on_btnCloseOropenSerial_clicked(bool checked);
private:
Ui::Widget *ui;
QSerialPort *serialPort;
int writeCntTotal;
int readCntTotal;
QString sendbak;
bool serialstatus;
};
#endif // WIDGET_H
widget.cpp
if(!serialstatus) //串口没打开
{
//1.选择端口号
serialPort->setPortName(ui->comboBox_serialNum_2->currentText());
//2.配置波特率
serialPort->setBaudRate(ui->comboBox_boautrate_2->currentText().toInt());
//3.配置数据位
serialPort->setDataBits(QSerialPort::DataBits(ui->comboBox_datait_2->currentText().toUInt()));
//4.配置校验位
switch(ui->comboBox_jiaoyan_2->currentIndex())
{
case 0:
serialPort->setParity(QSerialPort::NoParity);
break;
case 1:
serialPort->setParity(QSerialPort::EvenParity);
break;
case 2:
serialPort->setParity(QSerialPort::OddParity);
break;
case 3:
serialPort->setParity(QSerialPort::SpaceParity);
break;
case 4:
serialPort->setParity(QSerialPort::MarkParity);
break;
default:
serialPort->setParity(QSerialPort::UnknownParity);
break;
}
//5.配置停止位
serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_stopbit_2->currentText().toUInt()));
//6.流控
if(ui->comboBox_fileCon_2->currentText()=="None")
{
serialPort->setFlowControl(QSerialPort::NoFlowControl);
}
//7.打开串口
if(serialPort->open(QIODevice::ReadWrite)) //打开成功
{
qDebug()<<"serial open success!";
ui->comboBox_serialNum_2->setEnabled(false);
ui->comboBox_boautrate_2->setEnabled(false);
ui->comboBox_datait_2->setEnabled(false);
ui->comboBox_stopbit_2->setEnabled(false);
ui->comboBox_jiaoyan_2->setEnabled(false);
ui->comboBox_fileCon_2->setEnabled(false);
ui->btnCloseOropenSerial->setText("关闭串口");
ui->btnSendContext->setEnabled(true);
serialstatus=true; //串口打开
}
else
{
QMessageBox msgBox;
msgBox.setWindowTitle("打开串口错误");
msgBox.setText("打开失败,串口可能被占用!");
msgBox.exec();
}
}
else //串口打开置为没打开
{
serialPort->close();//关闭串口
ui->comboBox_serialNum_2->setEnabled(true);
ui->comboBox_boautrate_2->setEnabled(true);
ui->comboBox_datait_2->setEnabled(true);
ui->comboBox_stopbit_2->setEnabled(true);
ui->comboBox_jiaoyan_2->setEnabled(true);
ui->comboBox_fileCon_2->setEnabled(true);
ui->btnCloseOropenSerial->setText("打开串口");
ui->btnSendContext->setEnabled(false);
serialstatus=false; //串口失败
}
串口调试助手实现自动发送
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QSerialPort>
#include <QTimer>
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_btnCloseOropenSerial_clicked();
void on_btnSendContext_clicked();
void on_SerialData_readyToRead();
void on_btnCloseOropenSerial_clicked(bool checked);
void on_checkBSendInTime_clicked(bool checked);
private:
Ui::Widget *ui;
QSerialPort *serialPort;
int writeCntTotal;
int readCntTotal;
QString sendbak;
bool serialstatus;
QTimer *timer;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QSerialPortInfo>
#include <QDebug>
#include <QMessageBox>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setLayout(ui->gridLayoutGlobal);
writeCntTotal=0;
readCntTotal=0;
serialstatus=false;
serialPort=new QSerialPort(this);
timer=new QTimer(this);
ui->btnSendContext->setEnabled(false);
ui->checkBSendInTime->setEnabled(false);
connect(serialPort,&QSerialPort::readyRead,this,&Widget::on_SerialData_readyToRead); //接收数据
connect(timer,&QTimer::timeout,[=](){
on_btnSendContext_clicked(); //定时发送
});
ui->comboBox_boautrate_2->setCurrentIndex(6);//设置默认波特率为115200
ui->comboBox_datait_2->setCurrentIndex(3);//设置默认数据位为8位
QList<QSerialPortInfo> serialList=QSerialPortInfo::availablePorts(); //检测串口
for(QSerialPortInfo serialInfo:serialList)
{
qDebug()<<serialInfo.portName(); //打印串口号
ui->comboBox_serialNum_2->addItem(serialInfo.portName());//把检测的串口追加到控件中
}
}
Widget::~Widget()
{
delete ui;
}
//打开串口
void Widget::on_btnCloseOropenSerial_clicked()
{
/*
if(!serialstatus) //串口没打开
{
//1.选择端口号
serialPort->setPortName(ui->comboBox_serialNum_2->currentText());
//2.配置波特率
serialPort->setBaudRate(ui->comboBox_boautrate_2->currentText().toInt());
//3.配置数据位
serialPort->setDataBits(QSerialPort::DataBits(ui->comboBox_datait_2->currentText().toUInt()));
//4.配置校验位
switch(ui->comboBox_jiaoyan_2->currentIndex())
{
case 0:
serialPort->setParity(QSerialPort::NoParity);
break;
case 1:
serialPort->setParity(QSerialPort::EvenParity);
break;
case 2:
serialPort->setParity(QSerialPort::OddParity);
break;
case 3:
serialPort->setParity(QSerialPort::SpaceParity);
break;
case 4:
serialPort->setParity(QSerialPort::MarkParity);
break;
default:
serialPort->setParity(QSerialPort::UnknownParity);
break;
}
//5.配置停止位
serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_stopbit_2->currentText().toUInt()));
//6.流控
if(ui->comboBox_fileCon_2->currentText()=="None")
{
serialPort->setFlowControl(QSerialPort::NoFlowControl);
}
//7.打开串口
if(serialPort->open(QIODevice::ReadWrite)) //打开成功
{
qDebug()<<"serial open success!";
ui->comboBox_serialNum_2->setEnabled(false);
ui->comboBox_boautrate_2->setEnabled(false);
ui->comboBox_datait_2->setEnabled(false);
ui->comboBox_stopbit_2->setEnabled(false);
ui->comboBox_jiaoyan_2->setEnabled(false);
ui->comboBox_fileCon_2->setEnabled(false);
ui->btnCloseOropenSerial->setText("关闭串口");
ui->btnSendContext->setEnabled(true);
serialstatus=true; //串口打开
}
else
{
QMessageBox msgBox;
msgBox.setWindowTitle("打开串口错误");
msgBox.setText("打开失败,串口可能被占用!");
msgBox.exec();
}
}
else //串口打开置为没打开
{
serialPort->close();//关闭串口
ui->comboBox_serialNum_2->setEnabled(true);
ui->comboBox_boautrate_2->setEnabled(true);
ui->comboBox_datait_2->setEnabled(true);
ui->comboBox_stopbit_2->setEnabled(true);
ui->comboBox_jiaoyan_2->setEnabled(true);
ui->comboBox_fileCon_2->setEnabled(true);
ui->btnCloseOropenSerial->setText("打开串口");
ui->btnSendContext->setEnabled(false);
serialstatus=false; //串口失败
}
*/
}
//发数据
void Widget::on_btnSendContext_clicked()
{
int writeCnt=0;
const char* sendData=ui->lineEditsendcontext->text().toStdString().c_str();
writeCnt=serialPort->write(sendData);
if(writeCnt==-1) //发送失败
{
ui->labelSendStaus->setText("send Error!");
}
else //发送成功
{
writeCntTotal+=writeCnt;
qDebug()<<"send Ok!"<<sendData;
ui->labelSendStaus->setText("send OK!");
ui->labelSendcnt->setNum(writeCntTotal);
if(strcmp(sendData,sendbak.toStdString().c_str())!=0)
{
ui->textEditRecord->append(sendData);
sendbak=QString(sendData) ; //保存上一次记录
}
}
}
//收数据
void Widget::on_SerialData_readyToRead()
{
QString recvMessage=serialPort->readAll();
if(recvMessage!=NULL)
{
qDebug()<<"getMessage:"<<recvMessage;
ui->textEditRev->append(recvMessage);
readCntTotal+=recvMessage.size();
ui->labelRevcnt->setNum(readCntTotal);
}
}
//打开串口
void Widget::on_btnCloseOropenSerial_clicked(bool checked)
{
if(checked) //串口没打开
{
//1.选择端口号
serialPort->setPortName(ui->comboBox_serialNum_2->currentText());
//2.配置波特率
serialPort->setBaudRate(ui->comboBox_boautrate_2->currentText().toInt());
//3.配置数据位
serialPort->setDataBits(QSerialPort::DataBits(ui->comboBox_datait_2->currentText().toUInt()));
//4.配置校验位
switch(ui->comboBox_jiaoyan_2->currentIndex())
{
case 0:
serialPort->setParity(QSerialPort::NoParity);
break;
case 1:
serialPort->setParity(QSerialPort::EvenParity);
break;
case 2:
serialPort->setParity(QSerialPort::OddParity);
break;
case 3:
serialPort->setParity(QSerialPort::SpaceParity);
break;
case 4:
serialPort->setParity(QSerialPort::MarkParity);
break;
default:
serialPort->setParity(QSerialPort::UnknownParity);
break;
}
//5.配置停止位
serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_stopbit_2->currentText().toUInt()));
//6.流控
if(ui->comboBox_fileCon_2->currentText()=="None")
{
serialPort->setFlowControl(QSerialPort::NoFlowControl);
}
//7.打开串口
if(serialPort->open(QIODevice::ReadWrite)) //打开成功
{
qDebug()<<"serial open success!";
ui->comboBox_serialNum_2->setEnabled(false);
ui->comboBox_boautrate_2->setEnabled(false);
ui->comboBox_datait_2->setEnabled(false);
ui->comboBox_stopbit_2->setEnabled(false);
ui->comboBox_jiaoyan_2->setEnabled(false);
ui->comboBox_fileCon_2->setEnabled(false);
ui->btnCloseOropenSerial->setText("关闭串口");
ui->btnSendContext->setEnabled(true);
ui->checkBSendInTime->setEnabled(true);
}
else
{
QMessageBox msgBox;
msgBox.setWindowTitle("打开串口错误");
msgBox.setText("打开失败,串口可能被占用!");
msgBox.exec();
}
}
else //串口打开置为没打开
{
serialPort->close();//关闭串口
ui->comboBox_serialNum_2->setEnabled(true);
ui->comboBox_boautrate_2->setEnabled(true);
ui->comboBox_datait_2->setEnabled(true);
ui->comboBox_stopbit_2->setEnabled(true);
ui->comboBox_jiaoyan_2->setEnabled(true);
ui->comboBox_fileCon_2->setEnabled(true);
ui->btnCloseOropenSerial->setText("打开串口");
ui->btnSendContext->setEnabled(false);
ui->checkBSendInTime->setEnabled(false);
ui->checkBSendInTime->setCheckState(Qt::Unchecked);
// ui->lineEditTimeeach->setEnabled(false);
// ui->lineEditsendcontext->setEnabled(false);
timer->stop();
ui->lineEditTimeeach->setEnabled(true);
ui->lineEditsendcontext->setEnabled(true);
}
}
//定时发送
void Widget::on_checkBSendInTime_clicked(bool checked)
{
//qDebug()<<"checked:"<<checked;
if(checked)
{
timer->start(ui->lineEditTimeeach->text().toInt());
ui->lineEditTimeeach->setEnabled(false);
ui->lineEditsendcontext->setEnabled(false);
//on_btnSendContext_clicked();
}
else
{
timer->stop();
ui->lineEditTimeeach->setEnabled(true);
ui->lineEditsendcontext->setEnabled(true);
}
}
串口调试助手保存接收记录
//清空接收
void Widget::on_btnrevClear_clicked()
{
ui->textEditRev->setText("");
}
//保存接收
void Widget::on_btnrevSave_clicked()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
"F:/Qt/serialData.txt",
tr("Text(*.txt)"));
if(fileName!=NULL)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return;
QTextStream out(&file);
out << ui->textEditRev->toPlainText();
file.close();
}
}
串口调试助手时间显示
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QSerialPort>
#include <QTimer>
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_btnCloseOropenSerial_clicked();
void on_btnSendContext_clicked();
void on_SerialData_readyToRead();
void on_btnCloseOropenSerial_clicked(bool checked);
void on_checkBSendInTime_clicked(bool checked);
void on_btnrevClear_clicked();
void on_btnrevSave_clicked();
void timer_reflash();
private:
Ui::Widget *ui;
QSerialPort *serialPort;
int writeCntTotal;
int readCntTotal;
QString sendbak;
QString myTime;
bool serialstatus;
QTimer *timer;
void getSysTime();
};
#endif // WIDGET_H
widget.cpp
QTimer* getSysTimeTimer=new QTimer(this);
connect(getSysTimeTimer,SIGNAL(timeout()),this,SLOT(timer_reflash()));
getSysTimeTimer->start(100);
//刷新时间
void Widget::timer_reflash()
{
getSysTime();
ui->labelCurrentTime->setText(myTime);
}
//获得系统时间
void Widget::getSysTime()
{
QDateTime currentTime=QDateTime::currentDateTime();
QDate date=currentTime.date();
int year=date.year();
int month=date.month();
int day=date.day();
QTime time=currentTime.time();
int hour=time.hour();
int min=time.minute();
int sec=time.second();
myTime=QString("%1-%2-%3 %4:%5:%6")
.arg(year,2,10,QChar('0'))
.arg(month,2,10,QChar('0'))
.arg(day,2,10,QChar('0'))
.arg(hour,2,10,QChar('0'))
.arg(min,2,10,QChar('0'))
.arg(sec,2,10,QChar('0'));
}
串口调试助手关联HEX接收
//HEX显示
void Widget::on_checkBoxHexDisplay_clicked(bool checked)
{
if(checked)
{
//1.读取TextEdit上的内容
QString tmp=ui->textEditRev->toPlainText();
//2.转换成HEX
QByteArray qtmp=tmp.toUtf8();
qtmp=qtmp.toHex();
//3.显示
ui->textEditRev->setText(qtmp);
}
else
{
QString tmpHexString=ui->textEditRev->toPlainText();
QByteArray tmpHexQByteArray=tmpHexString.toUtf8();
QByteArray tmpQByteString=QByteArray::fromHex(tmpHexQByteArray);
ui->textEditRev->setText(tmpQByteString);
}
}
//收数据
void Widget::on_SerialData_readyToRead()
{
QString recvMessage=serialPort->readAll();
if(recvMessage!=NULL)
{
//qDebug()<<"getMessage:"<<recvMessage;
if(ui->checkBoxHexDisplay->isChecked())
{
//新接收的内容
QByteArray tmpHexString=recvMessage.toUtf8().toHex();
//原来控件的内容
QString tmpStringHex=ui->textEditRev->toPlainText();
tmpHexString=tmpStringHex.toUtf8()+tmpHexString;
ui->textEditRev->setText(tmpHexString);
}
else
{
if(ui->checkBrevTime->checkState()==Qt::Unchecked)
{
ui->textEditRev->append(recvMessage);
}
else if(ui->checkBrevTime->checkState()==Qt::Checked)
{
getSysTime();
ui->textEditRev->append("【"+myTime+"】"+recvMessage);
}
}
readCntTotal+=recvMessage.size();
//ui->labelRevcnt->setNum(readCntTotal);
ui->labelRevcnt->setText("Received:"+QString::number(readCntTotal));
}
}
串口调试助手HEX发送
if(ui->checkBHexSend->isChecked()) //按下HEX发送按键
{
QString tmp=ui->lineEditsendcontext->text(); //读出字符串内容
//1.判断是否是偶数位
QByteArray tmpArray=tmp.toLocal8Bit();
if(tmpArray.size()%2!=0)
{
ui->labelSendStaus->setText("Error Input");
return;
}
//2.判断是否符合16进制的表达
for(char c:tmpArray)
{
if(!std::isxdigit(c))
{
ui->labelSendStaus->setText("Error Input");
return;
}
}
//3.转换成16进制发送,输入1,变成1
QByteArray arraySend=QByteArray::fromHex(tmpArray);
writeCnt=serialPort->write(arraySend);
}
优化HEX显示
QString lastShow;
tmp=QString::fromUtf8(qtmp);
for(int i=0;i<tmp.size();i+=2)
{
lastShow+=tmp.mid(i,2)+" ";
}
ui->textEditRev->setText(lastShow.toUtf8());
加入发送新行和自动换行
//发数据
void Widget::on_btnSendContext_clicked()
{
int writeCnt=0;
const char* sendData=ui->lineEditsendcontext->text().toLocal8Bit().constData();
if(ui->checkBHexSend->isChecked()) //按下HEX发送按键
{
QString tmp=ui->lineEditsendcontext->text();
//1.判断是否是偶数位
QByteArray tmpArray=tmp.toLocal8Bit();
if(tmpArray.size()%2!=0)
{
ui->labelSendStaus->setText("Error Input");
return;
}
//2.判断是否符合16进制的表达
for(char c:tmpArray)
{
if(!std::isxdigit(c))
{
ui->labelSendStaus->setText("Error Input");
return;
}
}
if(ui->checkBSendnewLine->isChecked())
{
tmpArray.append("\r\n");
}
//3.转换成16进制发送,输入1,变成1
QByteArray arraySend=QByteArray::fromHex(tmpArray);
writeCnt=serialPort->write(arraySend);
}
else //没按下HEX发送按键
{
if(ui->checkBSendnewLine->isChecked()) //发送新行
{
qDebug()<<"发送新行";
QByteArray arrySendData(sendData,strlen(sendData));
arrySendData.append("\r\n");
writeCnt=serialPort->write(arrySendData);
}
else
{
writeCnt=serialPort->write(sendData);
}
}
if(writeCnt==-1) //发送失败
{
ui->labelSendStaus->setText("send Error!");
}
else //发送成功
{
writeCntTotal+=writeCnt;
qDebug()<<"send Ok!"<<sendData<<"sendcnt"<<writeCnt;
ui->labelSendStaus->setText("send OK!");
//ui->labelSendcnt->setNum(writeCntTotal);
ui->labelSendcnt->setText("Sent:"+QString::number(writeCntTotal));
if(strcmp(sendData,sendbak.toStdString().c_str())!=0)
{
ui->textEditRecord->append(sendData);
sendbak=QString::fromUtf8(sendData) ; //保存上一次记录
}
}
}
//收数据
void Widget::on_SerialData_readyToRead()
{
QString recvMessage=serialPort->readAll();
if(recvMessage!=NULL)
{
qDebug()<<"getMessage:"<<recvMessage<<"getMessage:"<<recvMessage.size();
if(ui->checkBoxLine->isChecked())
{
recvMessage.append("\r\n");
}
if(ui->checkBoxHexDisplay->isChecked())
{
//新接收的内容
QByteArray tmpHexString=recvMessage.toUtf8().toHex().toUpper();
//原来控件的内容
QString tmpStringHex=ui->textEditRev->toPlainText();
tmpHexString=tmpStringHex.toUtf8()+tmpHexString;
ui->textEditRev->setText(tmpHexString);
}
else
{
if(ui->checkBrevTime->checkState()==Qt::Unchecked)
{
ui->textEditRev->insertPlainText(recvMessage);
}
else if(ui->checkBrevTime->checkState()==Qt::Checked)
{
getSysTime();
ui->textEditRev->insertPlainText("【"+myTime+"】"+recvMessage);
}
}
readCntTotal+=recvMessage.size();
//ui->labelRevcnt->setNum(readCntTotal);
ui->labelRevcnt->setText("Received:"+QString::number(readCntTotal));
}
}
显示面板和显示历史
//显示或隐藏面板
void Widget::on_btnhideTable_clicked(bool checked)
{
if(checked)
{
ui->btnhideTable->setText("拓展面板");
ui->groupBoxTexts->hide();
}
else
{
ui->btnhideTable->setText("显示面板");
ui->groupBoxTexts->show();
}
}
//显示或隐藏历史
void Widget::on_btnHidehistory_clicked(bool checked)
{
if(checked)
{
ui->btnHidehistory->setText("显示历史");
ui->groupBoxRecord->hide();
}
else
{
ui->btnHidehistory->setText("隐藏历史");
ui->groupBoxRecord->show();
}
}
串口名字列表刷新
mycombobox.h
#ifndef MYCOMBOBOX_H
#define MYCOMBOBOX_H
#include <QWidget>
#include <QComboBox>
class MyComboBox : public QComboBox
{
Q_OBJECT;
public:
MyComboBox(QWidget *parent);
protected:
void mousePressEvent(QMouseEvent *e) override;
signals:
void refresh();
};
#endif // MYCOMBOBOX_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QSerialPort>
#include <QTimer>
#include <QWidget>
#include"mycombobox.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_btnCloseOropenSerial_clicked();
void on_btnSendContext_clicked();
void on_SerialData_readyToRead();
void on_btnCloseOropenSerial_clicked(bool checked);
void on_checkBSendInTime_clicked(bool checked);
void on_btnrevClear_clicked();
void on_btnrevSave_clicked();
void timer_reflash();
void on_checkBoxHexDisplay_clicked(bool checked);
void on_btnhideTable_clicked(bool checked);
void on_btnHidehistory_clicked(bool checked);
void refreshSerialName();
private:
Ui::Widget *ui;
QSerialPort *serialPort;
int writeCntTotal;
int readCntTotal;
QString sendbak;
QString myTime;
bool serialstatus;
QTimer *timer;
void getSysTime();
};
#endif // WIDGET_H
mycombobox.cpp
#include "mycombobox.h"
#include <QMouseEvent>
MyComboBox::MyComboBox(QWidget *parent):QComboBox(parent)
{
}
void MyComboBox::mousePressEvent(QMouseEvent *e)
{
//1.发送信号
if(e->button()==Qt::LeftButton)
{
emit refresh();
}
QComboBox::mousePressEvent(e);
}
widget.cpp
connect(ui->comboBox_serialNum_2,&MyComboBox::refresh,this,&Widget::refreshSerialName);
//串口刷新
void Widget::refreshSerialName()
{
ui->comboBox_serialNum_2->clear();
QList<QSerialPortInfo> serialList=QSerialPortInfo::availablePorts(); //检测串口
for(QSerialPortInfo serialInfo:serialList)
{
qDebug()<<serialInfo.portName(); //打印串口号
ui->comboBox_serialNum_2->addItem(serialInfo.portName());//把检测的串口追加到控件中
}
ui->labelSendStaus->setText("Com Refresh!");
}
调试多文本方法
void Widget::on_pushButton_clicked()
{
ui->lineEditsendcontext->setText(ui->lineEdit->text());
on_btnSendContext_clicked();
ui->checkBHexSend->setChecked(ui->checkBox->isChecked());
}
void Widget::on_pushButton_clicked()
{
ui->lineEditsendcontext->setText(ui->lineEdit->text());
on_btnSendContext_clicked();
// ui->checkBHexSend->setChecked(ui->checkBox->isChecked());
if(ui->checkBox->isChecked())
{
ui->checkBHexSend->setChecked(true);
}
else
{
ui->checkBHexSend->setChecked(false);
}
}
剩下的同理
方式二
QList<QPushButton*> buttons;
for(int i=1;i<=9;i++)
{
QString btnname=QString("pushButton_%1").arg(i);
QPushButton* btn=findChild<QPushButton*>(btnname);
if(btn)
{
btn->setProperty("buttonId",i);
buttons.append(btn);
connect(btn,SIGNAL(clicked()),this,SLOT(on_command_button_clicked()));
}
}
void Widget::on_command_button_clicked()
{
QPushButton *btn=qobject_cast<QPushButton*>(sender());
if(btn)
{
int num=btn->property("buttonId").toInt();
//qDebug()<<num;
QString lineEditname=QString("lineEdit_%1").arg(num);
QLineEdit* lineEdit=findChild< QLineEdit*>(lineEditname);
if(lineEdit)
ui->lineEditsendcontext->setText(lineEdit->text());
QString checkBoxname=QString("checkBox_%1").arg(num);
QCheckBox* checkBox=findChild< QCheckBox*>(checkBoxname);
if(checkBox)
ui->checkBHexSend->setChecked(checkBox->isChecked());
on_btnSendContext_clicked();
}
}
定时器优化循环发送
buttonsContimer=new QTimer(this);
//循环发送
connect(buttonsContimer,&QTimer::timeout,this,&Widget::buttons_handler);
void Widget::buttons_handler()
{
if(buttonsIndex<buttons.size())
{
QPushButton* btntmp=buttons[buttonsIndex];
emit btntmp->clicked();
buttonsIndex++;
}
else
{
buttonsIndex=0;
}
}
void Widget::on_checkBox_send_clicked(bool checked)
{
if(checked)
{
ui->spinBox->setEnabled(false);
buttonsContimer->start(ui->spinBox->text().toUInt());
}
else
{
ui->spinBox->setEnabled(true);
buttonsContimer->stop();
}
}
线程方式优化循环发送
customthread.h
#ifndef CUSTOMTHREAD_H
#define CUSTOMTHREAD_H
#include <QThread>
#include <QWidget>
class CustomThread : public QThread
{
Q_OBJECT
protected:
void run() override;
public:
CustomThread(QWidget *parent);
signals:
void threadTimeout();
};
#endif // CUSTOMTHREAD_H
customthread.cpp
#include "customthread.h"
void CustomThread::run()
{
while(true)
{
msleep(1000);
emit threadTimeout();
}
}
CustomThread::CustomThread(QWidget *parent):QThread(parent)
{
}
widget.cpp
void Widget::on_checkBox_send_clicked(bool checked)
{
if(checked)
{
ui->spinBox->setEnabled(false);
mythread->start();
//buttonsContimer->start(ui->spinBox->text().toUInt());
}
else
{
ui->spinBox->setEnabled(true);
mythread->terminate();
//buttonsContimer->stop();
}
}
重置功能实现
for(int i=1;i<=9;i++)
{
QString btnname=QString("pushButton_%1").arg(i);
QPushButton* btn=findChild<QPushButton*>(btnname);
if(btn)
{
btn->setProperty("buttonId",i);
buttons.append(btn);
connect(btn,SIGNAL(clicked()),this,SLOT(on_command_button_clicked()));
}
QString lineEditname=QString("lineEdit_%1").arg(i);
QLineEdit* lineEdit=findChild<QLineEdit*>(lineEditname);
lineEdits.append(lineEdit);
QString checkBoxname=QString("checkBox_%1").arg(i);
QCheckBox* checkBox=findChild<QCheckBox*>(checkBoxname);
checkBoxs.append(checkBox);
}
//重置功能
void Widget::on_btnInit_clicked()
{
QMessageBox msgBox;
msgBox.setWindowTitle("提示");
msgBox.setIcon(QMessageBox::Question);
msgBox.setText("重置列表不可逆,确定是否重置?");
QPushButton *yesbutton=msgBox.addButton("是",QMessageBox::YesRole);
QPushButton *nobutton=msgBox.addButton("否",QMessageBox::NoRole);
msgBox.exec();
if(msgBox.clickedButton()==yesbutton)
{
qDebug()<<"yesbutton";
for(int i=0;i<lineEdits.size();i++)
{
lineEdits[i]->clear();
checkBoxs[i]->setChecked(false);
}
}
if(msgBox.clickedButton()==nobutton)
{
qDebug()<<"nobutton";
}
}
保存功能实现
//多文本保存功能
void Widget::on_btnSave_clicked()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
"F:/",
tr("Text(*.txt)"));
if(fileName!=NULL)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return;
QTextStream out(&file);
for(int i=0;i<lineEdits.size();i++)
{
out << checkBoxs[i]->isChecked()<<","<<lineEdits[i]->text()<<"\n";
}
file.close();
}
}
载入功能
//多文本载入功能
void Widget::on_btnLoad_clicked()
{
int i=0;
QString fileName = QFileDialog::getOpenFileName(this, tr("Save File"),
"F:/",
tr("Text(*.txt)"));
if(fileName!=NULL)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file);
while(!in.atEnd())
{
QString line=in.readLine();
QStringList parts=line.split(",");
if(parts.count()==2)
{
checkBoxs[i]->setChecked(parts[0].toUInt());
lineEdits[i]->setText(parts[1]);
}
i++;
}
file.close();
}
}
完整代码
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QSerialPort>
#include <QPushButton>
#include <QTimer>
#include <QWidget>
#include <QCheckBox>
#include"mycombobox.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_btnCloseOropenSerial_clicked();
void on_btnSendContext_clicked();
void on_SerialData_readyToRead();
void on_btnCloseOropenSerial_clicked(bool checked);
void on_checkBSendInTime_clicked(bool checked);
void on_btnrevClear_clicked();
void on_btnrevSave_clicked();
void timer_reflash();
void on_checkBoxHexDisplay_clicked(bool checked);
void on_btnhideTable_clicked(bool checked);
void on_btnHidehistory_clicked(bool checked);
void refreshSerialName();
void on_command_button_clicked();
void on_checkBox_send_clicked(bool checked);
void buttons_handler();
void on_btnInit_clicked();
void on_btnSave_clicked();
void on_btnLoad_clicked();
private:
Ui::Widget *ui;
QSerialPort *serialPort;
int writeCntTotal;
int readCntTotal;
QString sendbak;
QString myTime;
bool serialstatus;
QTimer *timer;
void getSysTime();
int buttonsIndex;
QList<QPushButton*> buttons;
QList<QLineEdit*> lineEdits;
QList<QCheckBox*> checkBoxs;
QTimer *buttonsContimer;
};
#endif // WIDGET_H
mycombobox.h
#ifndef MYCOMBOBOX_H
#define MYCOMBOBOX_H
#include <QWidget>
#include <QComboBox>
class MyComboBox : public QComboBox
{
Q_OBJECT;
public:
MyComboBox(QWidget *parent);
protected:
void mousePressEvent(QMouseEvent *e) override;
signals:
void refresh();
};
#endif // MYCOMBOBOX_H
mian.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
mycombobox.cpp
#include "mycombobox.h"
#include <QMouseEvent>
MyComboBox::MyComboBox(QWidget *parent):QComboBox(parent)
{
}
void MyComboBox::mousePressEvent(QMouseEvent *e)
{
//1.发送信号
if(e->button()==Qt::LeftButton)
{
emit refresh();
}
QComboBox::mousePressEvent(e);
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QSerialPortInfo>
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
#include <qdatetime.h>
#include <QThread>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setLayout(ui->gridLayoutGlobal);
buttonsIndex=0;
writeCntTotal=0;
readCntTotal=0;
serialstatus=false;
serialPort=new QSerialPort(this);
timer=new QTimer(this);
ui->btnSendContext->setEnabled(false);
ui->checkBSendInTime->setEnabled(false);
ui->checkBSendnewLine->setEnabled(false);
ui->checkBHexSend->setEnabled(false);
ui->lineEditTimeeach->setEnabled(false);
QTimer* getSysTimeTimer=new QTimer(this);
buttonsContimer=new QTimer(this);
//循环发送
connect(buttonsContimer,&QTimer::timeout,this,&Widget::buttons_handler);
connect(getSysTimeTimer,SIGNAL(timeout()),this,SLOT(timer_reflash()));
getSysTimeTimer->start(100);
connect(serialPort,&QSerialPort::readyRead,this,&Widget::on_SerialData_readyToRead); //接收数据
connect(timer,&QTimer::timeout,[=](){
on_btnSendContext_clicked(); //定时发送
});
connect(ui->comboBox_serialNum_2,&MyComboBox::refresh,this,&Widget::refreshSerialName);
ui->comboBox_boautrate_2->setCurrentIndex(6);//设置默认波特率为115200
ui->comboBox_datait_2->setCurrentIndex(3);//设置默认数据位为8位
refreshSerialName();
ui->labelSendStaus->setText(ui->comboBox_serialNum_2->itemText(0)+"NotOpen!");
for(int i=1;i<=9;i++)
{
QString btnname=QString("pushButton_%1").arg(i);
QPushButton* btn=findChild<QPushButton*>(btnname);
if(btn)
{
btn->setProperty("buttonId",i);
buttons.append(btn);
connect(btn,SIGNAL(clicked()),this,SLOT(on_command_button_clicked()));
}
QString lineEditname=QString("lineEdit_%1").arg(i);
QLineEdit* lineEdit=findChild<QLineEdit*>(lineEditname);
lineEdits.append(lineEdit);
QString checkBoxname=QString("checkBox_%1").arg(i);
QCheckBox* checkBox=findChild<QCheckBox*>(checkBoxname);
checkBoxs.append(checkBox);
}
/*
//定义一个QList数组
QList<QPushButton *> button;
for(int i=1;i<=9;i++) //有9个按键
{
//组出button的名字
QString btnName=QString("pushButton_%1").arg(i);
//查找button的子控件
QPushButton* btn=findChild<QPushButton*>(btnName);
if(btn) //找到控件
{
btn->setProperty("buttonId",i);//借助发送者的属性,设定其他的控件的属性
//添加
button.append(btn); //添加到数组
connect(btn,SIGNAL(clicked()),this,SLOT(on_command_button_clicked())); //为当前控件做信号与槽
}
}
*/
}
Widget::~Widget()
{
delete ui;
}
//打开串口
void Widget::on_btnCloseOropenSerial_clicked()
{
/*
if(!serialstatus) //串口没打开
{
//1.选择端口号
serialPort->setPortName(ui->comboBox_serialNum_2->currentText());
//2.配置波特率
serialPort->setBaudRate(ui->comboBox_boautrate_2->currentText().toInt());
//3.配置数据位
serialPort->setDataBits(QSerialPort::DataBits(ui->comboBox_datait_2->currentText().toUInt()));
//4.配置校验位
switch(ui->comboBox_jiaoyan_2->currentIndex())
{
case 0:
serialPort->setParity(QSerialPort::NoParity);
break;
case 1:
serialPort->setParity(QSerialPort::EvenParity);
break;
case 2:
serialPort->setParity(QSerialPort::OddParity);
break;
case 3:
serialPort->setParity(QSerialPort::SpaceParity);
break;
case 4:
serialPort->setParity(QSerialPort::MarkParity);
break;
default:
serialPort->setParity(QSerialPort::UnknownParity);
break;
}
//5.配置停止位
serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_stopbit_2->currentText().toUInt()));
//6.流控
if(ui->comboBox_fileCon_2->currentText()=="None")
{
serialPort->setFlowControl(QSerialPort::NoFlowControl);
}
//7.打开串口
if(serialPort->open(QIODevice::ReadWrite)) //打开成功
{
qDebug()<<"serial open success!";
ui->comboBox_serialNum_2->setEnabled(false);
ui->comboBox_boautrate_2->setEnabled(false);
ui->comboBox_datait_2->setEnabled(false);
ui->comboBox_stopbit_2->setEnabled(false);
ui->comboBox_jiaoyan_2->setEnabled(false);
ui->comboBox_fileCon_2->setEnabled(false);
ui->btnCloseOropenSerial->setText("关闭串口");
ui->btnSendContext->setEnabled(true);
serialstatus=true; //串口打开
}
else
{
QMessageBox msgBox;
msgBox.setWindowTitle("打开串口错误");
msgBox.setText("打开失败,串口可能被占用!");
msgBox.exec();
}
}
else //串口打开置为没打开
{
serialPort->close();//关闭串口
ui->comboBox_serialNum_2->setEnabled(true);
ui->comboBox_boautrate_2->setEnabled(true);
ui->comboBox_datait_2->setEnabled(true);
ui->comboBox_stopbit_2->setEnabled(true);
ui->comboBox_jiaoyan_2->setEnabled(true);
ui->comboBox_fileCon_2->setEnabled(true);
ui->btnCloseOropenSerial->setText("打开串口");
ui->btnSendContext->setEnabled(false);
serialstatus=false; //串口失败
}
*/
}
//发数据
void Widget::on_btnSendContext_clicked()
{
int writeCnt=0;
const char* sendData=ui->lineEditsendcontext->text().toLocal8Bit().constData();
if(ui->checkBHexSend->isChecked()) //按下HEX发送按键
{
QString tmp=ui->lineEditsendcontext->text();
//1.判断是否是偶数位
QByteArray tmpArray=tmp.toLocal8Bit();
if(tmpArray.size()%2!=0)
{
ui->labelSendStaus->setText("Error Input");
QMessageBox msgBox;
msgBox.setWindowTitle("HEX发送");
msgBox.setText("Error Input!");
msgBox.exec();
return;
}
//2.判断是否符合16进制的表达
for(char c:tmpArray)
{
if(!std::isxdigit(c))
{
ui->labelSendStaus->setText("Error Input");
QMessageBox msgBox;
msgBox.setWindowTitle("HEX发送");
msgBox.setText("Error Input!");
msgBox.exec();
return;
}
}
if(ui->checkBSendnewLine->isChecked())
{
tmpArray.append("\r\n");
}
//3.转换成16进制发送,输入1,变成1
QByteArray arraySend=QByteArray::fromHex(tmpArray);
writeCnt=serialPort->write(arraySend);
}
else //没按下HEX发送按键
{
if(ui->checkBSendnewLine->isChecked()) //发送新行
{
qDebug()<<"发送新行";
QByteArray arrySendData(sendData,strlen(sendData));
arrySendData.append("\n");
writeCnt=serialPort->write(arrySendData);
}
else
{
writeCnt=serialPort->write(sendData);
}
}
if(writeCnt==-1) //发送失败
{
ui->labelSendStaus->setText("send Error!");
}
else //发送成功
{
writeCntTotal+=writeCnt;
qDebug()<<"send Ok!"<<sendData<<"sendcnt"<<writeCnt;
ui->labelSendStaus->setText("send OK!");
//ui->labelSendcnt->setNum(writeCntTotal);
ui->labelSendcnt->setText("Sent:"+QString::number(writeCntTotal));
if(strcmp(sendData,sendbak.toStdString().c_str())!=0)
{
ui->textEditRecord->append(sendData);
sendbak=QString::fromUtf8(sendData) ; //保存上一次记录
}
}
}
//收数据
void Widget::on_SerialData_readyToRead()
{
QString recvMessage=serialPort->readAll();
if(recvMessage!=NULL)
{
qDebug()<<"getMessage:"<<recvMessage<<"getMessage:"<<recvMessage.size();
if(ui->checkBoxLine->isChecked())
{
recvMessage.append("\r\n");
}
if(ui->checkBoxHexDisplay->isChecked())
{
//新接收的内容
QByteArray tmpHexString=recvMessage.toUtf8().toHex().toUpper();
//原来控件的内容
QString tmpStringHex=ui->textEditRev->toPlainText();
tmpHexString=tmpStringHex.toUtf8()+tmpHexString;
ui->textEditRev->setText(tmpHexString);
}
else
{
if(ui->checkBrevTime->checkState()==Qt::Unchecked)
{
ui->textEditRev->insertPlainText(recvMessage);
}
else if(ui->checkBrevTime->checkState()==Qt::Checked)
{
getSysTime();
ui->textEditRev->insertPlainText("【"+myTime+"】"+recvMessage);
}
}
readCntTotal+=recvMessage.size();
//ui->labelRevcnt->setNum(readCntTotal);
ui->labelRevcnt->setText("Received:"+QString::number(readCntTotal));
ui->textEditRev->moveCursor(QTextCursor::End);
ui->textEditRev->ensureCursorVisible();
//ui->textEditRev->setFocus();
}
}
//打开串口
void Widget::on_btnCloseOropenSerial_clicked(bool checked)
{
if(checked) //串口没打开
{
//1.选择端口号
serialPort->setPortName(ui->comboBox_serialNum_2->currentText());
//2.配置波特率
serialPort->setBaudRate(ui->comboBox_boautrate_2->currentText().toInt());
//3.配置数据位
serialPort->setDataBits(QSerialPort::DataBits(ui->comboBox_datait_2->currentText().toUInt()));
//4.配置校验位
switch(ui->comboBox_jiaoyan_2->currentIndex())
{
case 0:
serialPort->setParity(QSerialPort::NoParity);
break;
case 1:
serialPort->setParity(QSerialPort::EvenParity);
break;
case 2:
serialPort->setParity(QSerialPort::OddParity);
break;
case 3:
serialPort->setParity(QSerialPort::SpaceParity);
break;
case 4:
serialPort->setParity(QSerialPort::MarkParity);
break;
default:
serialPort->setParity(QSerialPort::UnknownParity);
break;
}
//5.配置停止位
serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_stopbit_2->currentText().toUInt()));
//6.流控
if(ui->comboBox_fileCon_2->currentText()=="None")
{
serialPort->setFlowControl(QSerialPort::NoFlowControl);
}
//7.打开串口
if(serialPort->open(QIODevice::ReadWrite)) //打开成功
{
qDebug()<<"serial open success!";
ui->comboBox_serialNum_2->setEnabled(false);
ui->comboBox_boautrate_2->setEnabled(false);
ui->comboBox_datait_2->setEnabled(false);
ui->comboBox_stopbit_2->setEnabled(false);
ui->comboBox_jiaoyan_2->setEnabled(false);
ui->comboBox_fileCon_2->setEnabled(false);
ui->btnCloseOropenSerial->setText("关闭串口");
ui->lineEditTimeeach->setEnabled(true);
ui->btnSendContext->setEnabled(true);
ui->checkBSendInTime->setEnabled(true);
ui->checkBSendnewLine->setEnabled(true);
ui->checkBHexSend->setEnabled(true);
ui->btnSave->setEnabled(true);
ui->btnLoad->setEnabled(true);
ui->btnInit->setEnabled(true);
ui->spinBox->setEnabled(true);
ui->labelSendStaus->setText(ui->comboBox_serialNum_2->itemText(0)+"Open!");
}
else
{
QMessageBox msgBox;
msgBox.setWindowTitle("打开串口错误");
msgBox.setText("打开失败,串口可能被占用!");
msgBox.exec();
}
}
else //关闭串口
{
serialPort->close();//关闭串口
ui->comboBox_serialNum_2->setEnabled(true);
ui->comboBox_boautrate_2->setEnabled(true);
ui->comboBox_datait_2->setEnabled(true);
ui->comboBox_stopbit_2->setEnabled(true);
ui->comboBox_jiaoyan_2->setEnabled(true);
ui->comboBox_fileCon_2->setEnabled(true);
ui->btnCloseOropenSerial->setText("打开串口");
ui->btnSendContext->setEnabled(false);
ui->checkBSendInTime->setEnabled(false);
// ui->checkBSendInTime->setCheckState(Qt::Unchecked);
ui->lineEditTimeeach->setEnabled(false);
// ui->lineEditsendcontext->setEnabled(false);
timer->stop();
ui->lineEditTimeeach->setEnabled(true);
ui->lineEditsendcontext->setEnabled(true);
ui->checkBSendnewLine->setEnabled(false);
ui->checkBHexSend->setEnabled(false);
ui->btnSave->setEnabled(false);
ui->btnLoad->setEnabled(false);
ui->btnInit->setEnabled(false);
ui->spinBox->setEnabled(false);
ui->labelSendStaus->setText(ui->comboBox_serialNum_2->itemText(0)+"NotOpen!");
}
}
//定时发送
void Widget::on_checkBSendInTime_clicked(bool checked)
{
//qDebug()<<"checked:"<<checked;
if(checked)
{
timer->start(ui->lineEditTimeeach->text().toInt());
ui->lineEditTimeeach->setEnabled(false);
ui->lineEditsendcontext->setEnabled(false);
//on_btnSendContext_clicked();
}
else
{
timer->stop();
ui->lineEditTimeeach->setEnabled(true);
ui->lineEditsendcontext->setEnabled(true);
}
}
//清空接收
void Widget::on_btnrevClear_clicked()
{
ui->textEditRev->setText("");
}
//保存接收
void Widget::on_btnrevSave_clicked()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
"F:/Qt/serialData.txt",
tr("Text(*.txt)"));
if(fileName!=NULL)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return;
QTextStream out(&file);
out << ui->textEditRev->toPlainText();
file.close();
}
}
//刷新时间
void Widget::timer_reflash()
{
getSysTime();
ui->labelCurrentTime->setText(myTime);
}
//获得系统时间
void Widget::getSysTime()
{
QDateTime currentTime=QDateTime::currentDateTime();
QDate date=currentTime.date();
int year=date.year();
int month=date.month();
int day=date.day();
QTime time=currentTime.time();
int hour=time.hour();
int min=time.minute();
int sec=time.second();
myTime=QString("%1-%2-%3 %4:%5:%6")
.arg(year,2,10,QChar('0'))
.arg(month,2,10,QChar('0'))
.arg(day,2,10,QChar('0'))
.arg(hour,2,10,QChar('0'))
.arg(min,2,10,QChar('0'))
.arg(sec,2,10,QChar('0'));
}
//HEX显示
void Widget::on_checkBoxHexDisplay_clicked(bool checked)
{
if(checked)
{
//1.读取TextEdit上的内容
QString tmp=ui->textEditRev->toPlainText();
//2.转换成HEX
QByteArray qtmp=tmp.toUtf8();
qtmp=qtmp.toHex();
//3.显示
QString lastShow;
tmp=QString::fromUtf8(qtmp);
for(int i=0;i<tmp.size();i+=2)
{
lastShow+=tmp.mid(i,2)+" ";
}
ui->textEditRev->setText(lastShow.toUtf8());
}
else
{
QString tmpHexString=ui->textEditRev->toPlainText();
QByteArray tmpHexQByteArray=tmpHexString.toUtf8();
QByteArray tmpQByteString=QByteArray::fromHex(tmpHexQByteArray);
ui->textEditRev->setText(tmpQByteString);
}
ui->textEditRev->moveCursor(QTextCursor::End);
ui->textEditRev->ensureCursorVisible();
}
//显示或隐藏面板
void Widget::on_btnhideTable_clicked(bool checked)
{
if(checked)
{
ui->btnhideTable->setText("拓展面板");
ui->groupBoxTexts->hide();
}
else
{
ui->btnhideTable->setText("显示面板");
ui->groupBoxTexts->show();
}
}
//显示或隐藏历史
void Widget::on_btnHidehistory_clicked(bool checked)
{
if(checked)
{
ui->btnHidehistory->setText("显示历史");
ui->groupBoxRecord->hide();
}
else
{
ui->btnHidehistory->setText("隐藏历史");
ui->groupBoxRecord->show();
}
}
//串口刷新
void Widget::refreshSerialName()
{
ui->comboBox_serialNum_2->clear();
QList<QSerialPortInfo> serialList=QSerialPortInfo::availablePorts(); //检测串口
for(QSerialPortInfo serialInfo:serialList)
{
qDebug()<<serialInfo.portName(); //打印串口号
ui->comboBox_serialNum_2->addItem(serialInfo.portName());//把检测的串口追加到控件中
}
ui->labelSendStaus->setText("Com Refresh!");
}
/*
void Widget::on_command_button_clicked()
{
//获得发送者发送的信号
QPushButton *btn=qobject_cast<QPushButton*>(sender());
if(btn)
{
//拿到按键编号
int num=btn->property("buttonId").toInt(); //把属性读出来
QString lineEditname=QString("lineEdit_%1").arg(num);
QLineEdit* lineEdit=findChild<QLineEdit*>(lineEditname);
if(lineEdit)
ui->lineEditsendcontext->setText(lineEdit->text());
QString checkBoxname=QString("checkBox_%1").arg(num);
QCheckBox* checkBox=findChild<QCheckBox*>(checkBoxname);
if(checkBox)
ui->checkBHexSend->setChecked(checkBox->isChecked());
on_btnSendContext_clicked();
}
}
*/
//多文本
void Widget::on_command_button_clicked()
{
QPushButton *btn=qobject_cast<QPushButton*>(sender());
if(btn)
{
int num=btn->property("buttonId").toInt();
//qDebug()<<num;
QString lineEditname=QString("lineEdit_%1").arg(num);
QLineEdit* lineEdit=findChild< QLineEdit*>(lineEditname);
if(lineEdit)
{
if(lineEdit->text().size()<=0)
{
return;
}
ui->lineEditsendcontext->setText(lineEdit->text());
}
QString checkBoxname=QString("checkBox_%1").arg(num);
QCheckBox* checkBox=findChild< QCheckBox*>(checkBoxname);
if(checkBox)
ui->checkBHexSend->setChecked(checkBox->isChecked());
on_btnSendContext_clicked();
}
}
void Widget::buttons_handler()
{
if(buttonsIndex<buttons.size())
{
QPushButton* btntmp=buttons[buttonsIndex];
emit btntmp->clicked();
buttonsIndex++;
}
else
{
buttonsIndex=0;
}
}
//循环发送
void Widget::on_checkBox_send_clicked(bool checked)
{
if(checked)
{
ui->spinBox->setEnabled(false);
buttonsContimer->start(ui->spinBox->text().toUInt());
}
else
{
ui->spinBox->setEnabled(true);
buttonsContimer->stop();
}
}
//多文本重置功能
void Widget::on_btnInit_clicked()
{
QMessageBox msgBox;
msgBox.setWindowTitle("提示");
msgBox.setIcon(QMessageBox::Question);
msgBox.setText("重置列表不可逆,确定是否重置?");
QPushButton *yesbutton=msgBox.addButton("是",QMessageBox::YesRole);
QPushButton *nobutton=msgBox.addButton("否",QMessageBox::NoRole);
msgBox.exec();
if(msgBox.clickedButton()==yesbutton)
{
qDebug()<<"yesbutton";
for(int i=0;i<lineEdits.size();i++)
{
lineEdits[i]->clear();
checkBoxs[i]->setChecked(false);
}
}
if(msgBox.clickedButton()==nobutton)
{
qDebug()<<"nobutton";
}
}
//多文本保存功能
void Widget::on_btnSave_clicked()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
"F:/",
tr("Text(*.txt)"));
if(fileName!=NULL)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return;
QTextStream out(&file);
for(int i=0;i<lineEdits.size();i++)
{
out << checkBoxs[i]->isChecked()<<","<<lineEdits[i]->text()<<"\n";
}
file.close();
}
}
//多文本载入功能
void Widget::on_btnLoad_clicked()
{
int i=0;
QString fileName = QFileDialog::getOpenFileName(this, tr("Save File"),
"F:/",
tr("Text(*.txt)"));
if(fileName!=NULL)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file);
while(!in.atEnd())
{
QString line=in.readLine();
QStringList parts=line.split(",");
if(parts.count()==2)
{
checkBoxs[i]->setChecked(parts[0].toUInt());
lineEdits[i]->setText(parts[1]);
}
i++;
}
file.close();
}
}