Qt實現串口助手
本文實例為大傢分享瞭Qt實現串口助手的具體代碼,供大傢參考,具體內容如下
1.界面佈局
這是一個常見的串口助手佈局。要說有什麼不常見,大概就是發送可以選擇編碼方式:GBK/UTF8
2.要點
沒什麼難度,就是水磨工夫,一點點寫。容易錯處的地方都寫在代碼註釋裡。
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); //添加數據位 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); //添加奇偶校驗位 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); //禁用發送按鈕 ui->btnSend->setEnabled(false); ui->btnOpen->setStatusTip(tr("打開/關閉串口")); ui->rdbGbk->setStatusTip("以GBK編碼發送" ); ui->rdbUtf8->setStatusTip(tr("以UTF8編碼發送")); } 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() != "關閉") { if( !ui->cbbPort->currentText().isNull() ) { ui->btnOpen->setText("關閉"); 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); } } //字符串數據轉為HEX,16進制形式。譬如將 “30”轉為“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轉為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 ; } //串口發送 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數據格式錯誤,\n數據形式類似: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.效果
測試可以發送和接收GK/UTF8編碼的數據。下圖是和ATK-XCOM通過虛擬串口交互。
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。