QT5 开发串口调试助手
近期在学习用QT开发桌面应用软件,使用QT5(5.12.0版本)开发了一个串口调试助手,废话不多说先放上运行效果图。
##源码我上传了,有需要的自取,链接:
https://download.csdn.net/download/liujj8189/87777867
简单分享一下部分核心功能的代码。
打开串口
/**
* 打开串口
* @brief MainWindow::openSerialPort
*/
bool MainWindow::OpenSerialPort()
{
//设置串口号、波特率等
mySerialPort->setPortName(ui->cmbPort->currentText());
mySerialPort->setBaudRate(ui->cmbBaudRate->currentText().toUInt());
mySerialPort->setDataBits(QSerialPort::DataBits(ui->cmbDataBits->currentText().toUInt()));
mySerialPort->setStopBits(QSerialPort::StopBits(ui->cmbStopBits->currentIndex()+1));
//校验位
switch (ui->cmbParity->currentIndex())
{
case 0:
mySerialPort->setParity(QSerialPort::NoParity);
break;
case 1:
mySerialPort->setParity(QSerialPort::OddParity);
break;
case 2:
mySerialPort->setParity(QSerialPort::EvenParity);
break;
default:
mySerialPort->setParity(QSerialPort::NoParity);
break;
}
//流控制
switch (ui->cmbFlowCtrl->currentIndex())
{
case 0:
mySerialPort->setFlowControl(QSerialPort::NoFlowControl);
break;
case 1:
mySerialPort->setFlowControl(QSerialPort::HardwareControl);
break;
case 2:
mySerialPort->setFlowControl(QSerialPort::SoftwareControl);
break;
default:
mySerialPort->setFlowControl(QSerialPort::NoFlowControl);
break;
}
//打开串口
bool res = mySerialPort->open(QIODevice::ReadWrite);
//绑定接收函数
connect(mySerialPort, SIGNAL(readyRead()), this, SLOT(readSerialPort()));
return res;
}
关闭串口
/**
* 关闭串口
* @brief MainWindow::CloseSerialPort
*/
void MainWindow::CloseSerialPort()
{
mySerialPort->close();
}
串口接收数据处理
/**
* 串口接收数据处理
* @brief MainWindow::readSerialPort
*/
void MainWindow::readSerialPort()
{
QByteArray buffer = mySerialPort->readAll();
if(buffer.isEmpty())
return;
QString printStr;
//16进制显示
if(ui->ckbRecvHex->isChecked())
{
for(int i = 0; i < buffer.count(); i++)
{
QString s;
s.sprintf("%02X ", (unsigned char)buffer.at(i));
//s.sprintf("0x%02x, ", (unsigned char)buffer.at(i));
printStr += s;
}
}
else
{
//设置编码方式
printStr = QTextCodec::codecForName("GBK")->toUnicode(buffer);
}
//添加回车换行
if(ui->ckbRecvAddLine->isChecked())
{
printStr+="\r\n";
}
ui->txbRecv->setText(ui->txbRecv->document()->toPlainText() + printStr);
ui->txbRecv->moveCursor(QTextCursor::End);
}
保存接收数据到文件中
/**
* 保存接收数据
* @brief MainWindow::on_actionSaveRecv_triggered
*/
void MainWindow::on_actionSaveRecv_triggered()
{
QString fileName = QFileDialog::getSaveFileName(this,z("保存数据"), ".",z("Text File (*.txt)"));
if (fileName.isEmpty())
{
return;
}
SaveFile(fileName);
}
bool MainWindow::SaveFile(const QString &fileName)
{
if (!WriteFile(fileName,ui->txbRecv->toPlainText()))
{
statusBar()->showMessage(z("保存数据失败"), 2000);
return false;
}
statusBar()->showMessage(z("数据已保存至文件"), 2000);
return true;
}
bool MainWindow::WriteFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::Append | QFile::Text))
{
QMessageBox::warning(this, z("保存数据"),z("无法写入文件 %1 : \n%2").arg(file.fileName()).arg(file.errorString()));
return false;
}
char* str=ui->txbRecv->toPlainText().toLocal8Bit().data();
file.write(str);
file.close();
return true;
}
/**
* 保存字符串到文件(追加)
* @brief MainWindow::WriteFile
* @param fileName 文件路径
* @param saveString 要保存的字符串
* @return 成功标志
*/
bool MainWindow::WriteFile(QString fileName,QString saveString)
{
QFile file(fileName);
if (!file.open(QIODevice::Append | QFile::Text))
{
return false;
}
char* str=saveString.toLocal8Bit().data();
file.write(str);
file.close();
return true;
}
发送数据
/**
* 发送数据
* @brief MainWindow::on_btnSend_clicked
*/
void MainWindow::on_btnSend_clicked()
{
QString dataStr = ui->txeSend->toPlainText();
//16进制发送
if(ui->ckbSendHex->isChecked())
{
if(ui->ckbSendAddLine->isChecked())
{
dataStr+="0D0A";
}
//删除所有的空格
dataStr.remove(QRegExp(" "));
//如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
if (dataStr.length() % 2)
{
dataStr.insert(dataStr.length()-1, '0');
}
QByteArray sendData;
StringToHex(dataStr, sendData);
SendData(sendData);
}
else
{
if(ui->ckbSendAddLine->isChecked())
{
dataStr+="\r\n";
}
QByteArray sendData = dataStr.toLocal8Bit();
SendData(sendData);
}
}
/**
* 发送数据
* @brief MainWindow::sendData
* @param data
*/
void MainWindow::SendData(QByteArray data)
{
if(data.isEmpty()||data.isNull())
return;
if(mySerialPort->isOpen())
{
mySerialPort->write(data);
}
}
16进制字符串转字节数组
/**
* 16进制字符串转字节数组
* @brief MainWindow::HexStringToByteArray
* @param str
* @return
*/
QByteArray MainWindow::HexStringToByteArray(QString str)
{
QByteArray res;
int hexdata,lowhexdata;
int hexdatalen = 0;
int len = str.length();
res.resize(len / 2);
char lstr,hstr;
for (int i = 0; i < len; )
{
hstr = str[i].toLatin1();
if (hstr == ' ')
{
++i;
continue;
}
++i;
if (i >= len) break;
lstr = str[i].toLatin1();
hexdata = ConvertHexChar(hstr);
lowhexdata = ConvertHexChar(lstr);
if ((hexdata == 16) || (lowhexdata == 16))
break;
else
hexdata = hexdata*16 + lowhexdata;
++i;
res[hexdatalen] = (char)hexdata;
++hexdatalen;
}
res.resize(hexdatalen);
return res;
}
字节数组转16进制字符串
/**
* 字节数组转16进制字符串
* @brief MainWindow::ByteArrayToHexString
* @param data
* @return
*/
QString MainWindow::ByteArrayToHexString(QByteArray data)
{
QString res(data.toHex().toUpper());
int length=res.length()/2;
for(int i=0;i<length;i++)
{
res.insert(2*i+i-1," ");
}
return res;
}
剩下的代码就不一一复制粘贴了,有兴趣的可以自己下回来看。下载链接:
https://download.csdn.net/download/liujj8189/87777867