好久之前写的了,突然有时间,贴一贴代码,好像还有个小问题没解决,忘了,自己可以试试吧。不过我觉得最大的问题是我这个软件大了点,网上下载的那些调试助手才不到10M。但是应该没机会优化了。如果有人优化了,希望能提醒一下。感谢!
界面
代码
头文件,没啥注释,全是按钮的槽函数
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <qserialport.h>
#include <qtimer.h>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void init();
QByteArray QString2QByteArray(QString);
private slots:
void on_btnOpen_clicked();
void on_btnClose_clicked();
void on_btnSend_clicked();
void on_btnUpdate_clicked();
void on_btnExit_clicked();
void on_checkHexSend_clicked(bool);
void on_checkHexShow_clicked(bool);
void on_textSend_cursorPositionChanged();
void on_checkTiming_toggled(bool);
void on_btnOpenFile_clicked();
void on_btnSendFile_clicked();
void on_btnStopSending_clicked();
void on_btnSave_clicked();
void readData();
private:
Ui::MainWindow *ui;
QSerialPort* serial_;
QTimer* timer;
QByteArray sendTxt, receiveTxt;
};
#endif // MAINWINDOW_H
C文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qserialportinfo.h>
#include <qmessagebox.h>
#include <qfiledialog.h>
#include <qfile.h>
#include <qtextstream.h>
#include <qtextcodec.h>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
init();
}
MainWindow::~MainWindow()
{
if(serial_)
delete serial_;
if(timer)
delete timer;
delete ui;
}
void MainWindow::init()
{
serial_=new QSerialPort(this);
timer = new QTimer(this);
//接收区不可编辑
ui->textReceive->setReadOnly(true);
//查找可用的串口
foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))
{
ui->comboPorts->addItem(serial.portName());
serial.close();
}
}
//查找文本编码方式
QList<QByteArray> codecList = QTextCodec::availableCodecs();
QString temp;
foreach(const auto codec, codecList){
ui->comboCodec->addItem(codec);
}
}
QByteArray MainWindow::QString2QByteArray(QString s)
{
QByteArray result;
bool ok;
QStringList temp = s.split(' ');
for(QString str : temp){
if(str.size() < 2)
result.push_back(str.toInt(&ok, 16));
else{
while(!str.isEmpty()){
result.push_back(quint8(str.left(2).toUInt(&ok, 16)));
str = str.remove(0,2);
}
}
}
return result;
}
void MainWindow::readData()
{
QByteArray buf; //二进制
buf=serial_->readAll();
quint64 i = buf.size();
if(!buf.isEmpty())
{
QString str;
if(ui->checkHexShow->isChecked()){
for(quint16 i = 0; i < buf.size(); i++){
str += QString::number(quint8(buf.at(i)),16) + " ";
}
ui->textReceive->insertPlainText(str);
}
else{
str = QString::fromLocal8Bit(buf);
ui->textReceive->insertPlainText(str);
}
}
buf.clear();
}
void MainWindow::on_btnOpen_clicked()
{
serial_->setPortName(ui->comboPorts->currentText());//设置串口名称
serial_->open(QIODevice::ReadWrite);//打开串口
//设置波特率
switch (ui->comboBuad->currentIndex())
{
case 0:
serial_->setBaudRate(QSerialPort::Baud1200);
break;
case 1:
serial_->setBaudRate(QSerialPort::Baud2400);
break;
case 2:
serial_->setBaudRate(QSerialPort::Baud4800);
break;
case 3:
serial_->setBaudRate(QSerialPort::Baud9600);
break;
case 4:
serial_->setBaudRate(QSerialPort::Baud19200);
break;
case 5:
serial_->setBaudRate(QSerialPort::Baud38400);
break;
case 6:
serial_->setBaudRate(QSerialPort::Baud57600);
break;
case 7:
serial_->setBaudRate(QSerialPort::Baud115200);
break;
default:
break;
}
//设置校验位
switch (ui->comboCheckBit->currentIndex())
{
case 0:
serial_->setParity(QSerialPort::NoParity);
break;
case 1:
serial_->setParity(QSerialPort::OddParity);
break;
case 2:
serial_->setParity(QSerialPort::EvenParity);
default:
break;
}
//设置停止位
switch (ui->comboStopBit->currentIndex())
{
case 1:
serial_->setStopBits(QSerialPort::OneStop);//停止位设置为1
break;
case 2:
serial_->setStopBits(QSerialPort::OneAndHalfStop);
break;
case 3:
serial_->setStopBits(QSerialPort::TwoStop);//
break;
default:
break;
}
//设置数据位
switch(ui->comboDataBit->currentIndex()){
case 0:
serial_->setDataBits(QSerialPort::Data8);
break;
case 1:
serial_->setDataBits(QSerialPort::Data7);
break;
case 2:
serial_->setDataBits(QSerialPort::Data6);
break;
case 3:
serial_->setDataBits(QSerialPort::Data5);
break;
}
//设置流控制
serial_->setFlowControl(QSerialPort::NoFlowControl);//设置为无流控制
//设置缓冲区大小
ui->comboPorts->setEnabled(false);
ui->comboBuad->setEnabled(false);
ui->comboDataBit->setEnabled(false);
ui->comboCheckBit->setEnabled(false);
ui->comboStopBit->setEnabled(false);
//连接信号槽
QObject::connect(serial_,SIGNAL(readyRead()),this,SLOT(readData()));
}
void MainWindow::on_btnClose_clicked()
{
serial_->clear();
serial_->close();
//serial_->deleteLater();
ui->comboPorts->setEnabled(true);
ui->comboBuad->setEnabled(true);
ui->comboDataBit->setEnabled(true);
ui->comboCheckBit->setEnabled(true);
ui->comboStopBit->setEnabled(true);
//QObject::disconnect(serial_,SIGNAL(readyRead()),this,SLOT(readData()));
}
void MainWindow::on_btnSend_clicked()
{
QString str = ui->textSend->toPlainText();
if(ui->checkNewLine->isChecked())
str += '\n';
if(ui->checkHexSend->isChecked()){
sendTxt = QString2QByteArray(str);
}
else{
sendTxt = str.toLocal8Bit();
}
serial_->write(sendTxt);//Latin1是ISO-8859-1的别名,单片机仅能识别ASCII码
}
void MainWindow::on_btnUpdate_clicked()
{
ui->comboPorts->clear();
//查找可用的串口
foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))
{
ui->comboPorts->addItem(serial.portName());
serial.close();
}
}
}
void MainWindow::on_btnExit_clicked()
{
if(serial_->isOpen())
serial_->close();
this->close();
}
void MainWindow::on_checkHexSend_clicked(bool checked)
{
QString s;
if(checked == true){
sendTxt = ui->textSend->toPlainText().toLocal8Bit();
for(quint16 i = 0; i < sendTxt.size(); i++){
s += QString::number(quint8(sendTxt.at(i)), 16) + " ";
}
ui->textSend->setText(s);
}
else{
sendTxt = QString2QByteArray(ui->textSend->toPlainText());
ui->textSend->setText(QString::fromLocal8Bit(sendTxt));
}
}
void MainWindow::on_checkHexShow_clicked(bool checked)
{
QString s;
if(checked == true){
receiveTxt = ui->textReceive->toPlainText().toLocal8Bit();
for(quint16 i = 0; i < receiveTxt.size(); i++){
s += QString::number(quint8(receiveTxt.at(i)), 16) + " ";
}
ui->textReceive->setText(s);
}
else{
receiveTxt = QString2QByteArray(ui->textReceive->toPlainText());
ui->textReceive->setText(QString::fromLocal8Bit(receiveTxt));
}
}
void MainWindow::on_textSend_cursorPositionChanged()
{
if(!ui->checkHexSend->isChecked())
return;
else{
//if(ui->textSend->cur)
//if(ui->textSend->toPlainText().isEmpty())
// return;
int pos = ui->textSend->textCursor().position();
if(pos == 0)
return;
QChar m = ui->textSend->toPlainText().at(pos - 1);
if((m == ' '))
return;
else if(m == '\n')
return;
else if( m >= '0' && m <= '9')
return;
else if( m >= 'a' && m <= 'f')
return;
else if(m >= 'A' && m <= 'F')
return;
else {
ui->textSend->textCursor().deletePreviousChar(); //删除该字符
QMessageBox::warning(this, tr("提醒"), tr("请输入十六进制数据!"), QMessageBox::Ok);
}
}
}
void MainWindow::on_checkTiming_toggled(bool checked)
{
if(checked){
connect(timer, SIGNAL(timeout()), this, SLOT(on_btnSend_clicked()));
timer->start(ui->textTimePeriod->text().toUInt());
ui->textTimePeriod->setEnabled(false);
}
else{
disconnect(timer, SIGNAL(timeout()), this, SLOT(on_btnSend_clicked()));
timer->stop();
ui->textTimePeriod->setEnabled(true);
}
}
void MainWindow::on_btnOpenFile_clicked()
{
QString path = QFileDialog::getOpenFileName(this,
QString::fromUtf8("请选择一个文件"),
qApp->applicationFilePath(),
QString::asprintf("txt(*.txt);;*.*"));
if (path.isEmpty()) {
QMessageBox::warning(this, tr("提醒"), tr("未选择文件!"), QMessageBox::StandardButton::Ok);
return;
}
ui->textFileName->setText(path.toUtf8());
}
void MainWindow::on_btnSendFile_clicked()
{
if(!serial_->isOpen()){
ui->statusbar->showMessage(tr("错误:未打开串口!"));
return;
}
if(ui->textFileName->text().isEmpty()){
ui->statusbar->showMessage(tr("错误:未选择文件!"));
return;
}
QFile file(ui->textFileName->text());
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
QMessageBox::question(this, tr("错误"), tr("无法读取文件!"), QMessageBox::StandardButton::Ok);
}
QFileInfo fileinfo(file);
quint64 current = 0;
quint64 total = fileinfo.size();
ui->progressBar->setRange(0, total);
QTextStream in(&file);
in.setCodec(ui->comboCodec->currentText().toLocal8Bit()); // 设置文件的编码格式为UTF-8
QString line = in.readLine(); // 此时以UTF-8的方式从文件中读取内容,结果正常
QByteArray lineByte;
while(!line.isNull()){
line += '\n';
lineByte = line.toLocal8Bit();
serial_->write(lineByte);
current += lineByte.size();
ui->progressBar->setValue(current);
line = in.readLine();
if(current >= 4000)
serial_->flush();
}
serial_->flush();
file.close(); //关闭文件
ui->progressBar->setValue(total);
QMessageBox::information(this, tr("成功!"), tr("文件发送成功"), QMessageBox::Ok);
ui->progressBar->setValue(0);
}
void MainWindow::on_btnSave_clicked()
{
QString path = QFileDialog::getSaveFileName(this,
QString::fromUtf8("请选择一个文件"),
qApp->applicationFilePath(),
QString::asprintf("txt(*.txt);;*.*"));
if (path.isEmpty()) {
QMessageBox::warning(this, tr("提醒"), tr("未选择文件!"), QMessageBox::StandardButton::Ok);
return;
}
QFile file(path);
file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&file);
out.setCodec("UTF-8"); // 设置文件的编码格式为UTF-8
out << ui->textReceive->toPlainText();
out.flush();
file.close(); //关闭文件
ui->statusbar->showMessage(tr("数据保存成功!"));
}
void MainWindow::on_btnStopSending_clicked()
{
}
总结
gbb YYDS