Qt實(shí)現(xiàn)串口助手
本文實(shí)例為大家分享了Qt實(shí)現(xiàn)串口助手的具體代碼,供大家參考,具體內(nèi)容如下
1.界面布局
這是一個常見的串口助手布局。要說有什么不常見,大概就是發(fā)送可以選擇編碼方式:GBK/UTF8
2.要點(diǎn)
沒什么難度,就是水磨工夫,一點(diǎn)點(diǎn)寫。容易錯處的地方都寫在代碼注釋里。
3.代碼
下面是 mainwindow.cpp 文件。
#include "mainwindow.h" #include "ui_mainwindow.h" #include <qdebug.h> ? QSerialPort *serial; ? MainWindow::MainWindow(QWidget *parent) : ? ? QMainWindow(parent), ? ? ui(new Ui::MainWindow) { ? ? ui->setupUi(this); ? ? serial = new QSerialPort; ? ? ? findSerialPort(); ? ? ? ui->cbbBaudrate->addItem(QStringLiteral("4800"), QSerialPort::Baud4800); ? ? ui->cbbBaudrate->addItem(QStringLiteral("9600"), QSerialPort::Baud9600); ? ? ui->cbbBaudrate->addItem(QStringLiteral("19200"), QSerialPort::Baud19200); ? ? ui->cbbBaudrate->addItem(QStringLiteral("38400"), QSerialPort::Baud38400); ? ? ui->cbbBaudrate->addItem(QStringLiteral("115200"), QSerialPort::Baud115200); ? ? ui->cbbBaudrate->setCurrentIndex(4); ? ? //添加數(shù)據(jù)位 ? ? ?ui->cbbDataSize->addItem(QStringLiteral("5"), QSerialPort::Data5); ? ? ?ui->cbbDataSize->addItem(QStringLiteral("6"), QSerialPort::Data6); ? ? ?ui->cbbDataSize->addItem(QStringLiteral("7"), QSerialPort::Data7); ? ? ?ui->cbbDataSize->addItem(QStringLiteral("8"), QSerialPort::Data8); ? ? ?ui->cbbDataSize->setCurrentIndex(3); ? ? ?//添加奇偶校驗(yàn)位 ? ? ?ui->cbbParity->addItem(tr("None"), QSerialPort::NoParity); ? ? ?ui->cbbParity->addItem(tr("Even"), QSerialPort::EvenParity); ? ? ?ui->cbbParity->addItem(tr("Odd"), QSerialPort::OddParity); ? ? ?ui->cbbParity->addItem(tr("Mark"), QSerialPort::MarkParity); ? ? ?ui->cbbParity->addItem(tr("Space"), QSerialPort::SpaceParity); ? ? ?ui->cbbParity->setCurrentIndex(0); ? ? ?//添加停止位 ? ? ?ui->cbbStopbit->addItem(QStringLiteral("1"), QSerialPort::OneStop); ? ? ?ui->cbbStopbit->addItem(QStringLiteral("1.5"), QSerialPort::OneAndHalfStop);// ? ? ?ui->cbbStopbit->addItem(QStringLiteral("2"), QSerialPort::TwoStop); ? ? ?ui->cbbStopbit->setCurrentIndex(0); ? ? ?//添加流控位 ? ? ?ui->cbbFlowbit->addItem(tr("None"), QSerialPort::NoFlowControl); ? ? ?ui->cbbFlowbit->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl); ? ? ?ui->cbbFlowbit->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl); ? ? ?ui->cbbFlowbit->setCurrentIndex(0); ? ? ?//禁用發(fā)送按鈕 ? ? ?ui->btnSend->setEnabled(false); ? ? ? ?ui->btnOpen->setStatusTip(tr("打開/關(guān)閉串口")); ? ? ?ui->rdbGbk->setStatusTip("以GBK編碼發(fā)送" ); ? ? ?ui->rdbUtf8->setStatusTip(tr("以UTF8編碼發(fā)送")); } ? MainWindow::~MainWindow() { ? ? delete ui; } ? void MainWindow::findSerialPort() { ? ? ui->cbbPort->clear(); ? ? foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) ? ? { ? ? ? ? QSerialPort tempserial; ? ? ? ? tempserial.setPort(info); ? ? ? ? ? if(tempserial.open(QIODevice::ReadWrite)) ? ? ? ? { ? ? ? ? ? ? ui->cbbPort->addItem(info.description()+":"+tempserial.portName(),tempserial.portName()); ? ? ? ? ? ? ? tempserial.close(); ? ? ? ? } ? ? } } ? void MainWindow::setsuienable( bool en ) { ? ? ui->cbbPort->setEnabled(en); ? ? ui->cbbBaudrate->setEnabled(en); ? ? ui->cbbDataSize->setEnabled(en); ? ? ui->cbbParity->setEnabled(en); ? ? ui->cbbStopbit->setEnabled(en); ? ? ui->cbbFlowbit->setEnabled(en); } ? void MainWindow::on_btnOpen_clicked() { ? ? if(ui->btnOpen->text() ?!= "關(guān)閉") ? ? { ? ? ? ? if( !ui->cbbPort->currentText().isNull() ) ? ? ? ? { ? ? ? ? ? ? ? ui->btnOpen->setText("關(guān)閉"); ? ? ? ? ? ? ui->btnSend->setEnabled(true); ? ? ? ? ? ? ui->btnFind->setEnabled(false); ? ? ? ? ? ? setsuienable(false); ? ? ? ? ? ? ? serial->setPortName(ui->cbbPort->currentData(Qt::UserRole).value<QString>() ?); ? ? ? ? ? ? serial->setBaudRate(ui->cbbBaudrate->currentData(Qt::UserRole).value<qint32>() ); ? ? ? ? ? ? serial->setDataBits(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::DataBits>() ); ? ? ? ? ? ? serial->setFlowControl(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::FlowControl>() ); ? ? ? ? ? ? serial->setParity(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::Parity>() ); ? ? ? ? ? ? serial->setStopBits(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::StopBits>() ); ? ? ? ? ? ? serial->open(QIODevice::ReadWrite); ? ? ? ? ? ? ? ? connect(serial, &QSerialPort::readyRead, this, &MainWindow::serialReadData); ? ? ? ? } ? ? } ? ? else ? ? { ? ? ? ? serial->close(); ? ? ? ? setsuienable(true); ? ? ? ? ui->btnSend->setEnabled(false); ? ? ? ? ui->btnOpen->setText("打開"); ? ? ? ? ui->btnFind->setEnabled(true); ? ? } } ? //字符串?dāng)?shù)據(jù)轉(zhuǎn)為HEX,16進(jìn)制形式。譬如將 “30”轉(zhuǎn)為“0” bool StringToHex( QString &dst,const QString src ) { ? ? QStringList list = src.trimmed().split(QRegExp("\t|\n|\r\n|\r| |,|;")); //去除頭尾空白,再分割 ? ? ? foreach (QString n, ?list ) ? ? { ? ? ? ? bool res; ? ? ? ? if(n.isEmpty())continue; ? ? ? ? int d= n.toInt(&res,16); ? ? ? ? if(d>255){ ?return ?false ;} ? ? ? ? ? char ?c = d; ? ? ? ? if(res) ? ? ? ? ? ? dst.append(c); ? ? ? ? else ? ? ? ? ? ? return ?false ; ? ? } ? ? return true; } //UTF8轉(zhuǎn)為GBK QByteArray Utf8ToGbk(QByteArray buf) { ? ? QTextCodec* Utf8Codec = QTextCodec::codecForName("UTF-8"); ? ? QTextCodec::setCodecForLocale(Utf8Codec); ? ? QTextCodec* GbkCodec = QTextCodec::codecForName("GBK"); ? ? ? QByteArray ByteGbk = GbkCodec->fromUnicode( Utf8Codec->toUnicode( buf ) ); ? //先Unicode編碼,后arr ? ? ? return ?ByteGbk ; } //串口發(fā)送 void MainWindow::on_btnSend_clicked() { ? ? if( ui->teSend->toPlainText() .isEmpty() )return; ? ? ? if( ui->ckbSendhex->isChecked() ?) ? ? { ? ? ? ? QString txt; ? ? ? ? if( StringToHex( txt ,ui->teSend->toPlainText() ) ) ? ? ? ? { ? ? ? ? ? ? serial->write( txt.toLatin1() ?); ? ? ? ? }else ? ? ? ? { ? ? ? ? ? ? QMessageBox::about(this,tr("提示"),tr("HEX數(shù)據(jù)格式錯誤,\n數(shù)據(jù)形式類似:30 34 56")); ? ? ? ? } ? ? } ? ? else{ ? ? ? ? if( ui->rdbUtf8->isChecked() ) ? ? ? ? { ? ? ? ? ? ? serial->write( ui->teSend->toPlainText().toUtf8() ? ); ? ? ? ? }else ? ? ? ? { ? ? ? ? ? ? QByteArray arrutf8 =ui->teSend->toPlainText().toLocal8Bit(); ? ? ? ? ? ? serial->write( Utf8ToGbk(arrutf8) ? ); ? ? ? ? } ? ? } } ? //串口接收處理 void MainWindow::serialReadData() { ? ?//注意,直接append會從下一行開始,所以先放入QString ? ? QByteArray buf = serial->readAll(); ? ? if(!buf.isEmpty()) ? ? { ? ? ? ? QString txt = ui->teReceive->toPlainText(); ? ? ? ? ? if( ui->ckbReceivehex->isChecked() ) ? ? ? ? { ? ? ? ? ? ? ui->teReceive->append( QString( buf.toHex(' ') ) ); ? ? ? ? } ? ? ? ? else ? ? ? ? { ? ? ? ? ? ? QTextCodec::ConverterState state; ? ? ? ? ? ? QTextCodec *codec = QTextCodec::codecForName("UTF-8"); ? ? ? ? ? ? QString str = codec->toUnicode( buf.constData(), buf.size(), &state); ? ? ? ? ? ? if ( state.invalidChars ) ? ? ? ? ? ? { ? ? ? ? ? ? ? ?str = QTextCodec::codecForName( "GBK" )->toUnicode(buf); ? ? ? ? ? ? } ? ? ? ? ? ? else ? ? ? ? ? ? { ? ? ? ? ? ? ? ?str = ?codec->toUnicode(buf); ? ? ? ? ? ? } ? ? ? ? ? ? ui->teReceive->clear(); ? ? ? ? ? ? ui->teReceive->append( ?txt+str ?); ? ? ? ? } ? ? } ? } ? void MainWindow::on_btnClearReceive_clicked() { ? ? ui->teReceive->clear(); } ? void MainWindow::on_btnClearSend_clicked() { ? ? ui->teSend->clear(); } ? void MainWindow::on_btnFind_clicked() { ? ? ui->btnFind->setEnabled(false); ? ? findSerialPort(); ? ? ui->btnFind->setEnabled(true); }
4.效果
測試可以發(fā)送和接收GK/UTF8編碼的數(shù)據(jù)。下圖是和ATK-XCOM通過虛擬串口交互。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++詳細(xì)講解函數(shù)調(diào)用與Struct和CLass的區(qū)別
主調(diào)函數(shù)使用被調(diào)函數(shù)的功能,稱為函數(shù)調(diào)用。在C語言/C++中,只有在函數(shù)調(diào)用時(shí),函數(shù)體中定義的功能才會被執(zhí)行,下面讓我們詳細(xì)來了解2022-05-05C++編寫實(shí)現(xiàn)圖書管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++編寫實(shí)現(xiàn)圖書管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C++?JSON庫?nlohmann::basic_json::array?的用法示例詳解
nlohmann::json是一個C++的JSON庫,它提供了一種容易和直觀的方法來處理JSON數(shù)據(jù),nlohmann::json::array()是用來創(chuàng)建一個JSON數(shù)組的方法,這篇文章主要介紹了C++ JSON庫nlohmann::basic_json::array的用法,需要的朋友可以參考下2023-06-06C++數(shù)據(jù)結(jié)構(gòu)之搜索二叉樹的實(shí)現(xiàn)
了解搜索二叉樹是為了STL中的map和set做鋪墊,我們所熟知的AVL樹和平衡搜索二叉樹也需要搜索二叉樹的基礎(chǔ)。本文將詳解如何利用C++實(shí)現(xiàn)搜索二叉樹,需要的可以參考一下2022-05-05