1. 程式人生 > 程式設計 >Qt串列埠通訊開發之Qt串列埠通訊模組QSerialPort開發完整例項(串列埠助手開發)

Qt串列埠通訊開發之Qt串列埠通訊模組QSerialPort開發完整例項(串列埠助手開發)

之前自己寫了用於上位機做基本收發的介面,獨立出來相當於一個串列埠助手,先貼圖:

Qt串列埠通訊開發之Qt串列埠通訊模組QSerialPort開發完整例項(串列埠助手開發)

功能作為串列埠助手來說還算完善,五個傳送槽,一個接收槽,可以檢測可用串列埠並加上相關標誌,串列埠設定,記數功能,還有選單欄上的檔案操作和一些選擇功能。

下面說一說這個專案:

做這個串列埠助手分為兩步,第一步是設計介面,第二部是功能的程式碼實現。

一、介面設計

介面設計用Qt Designer,當然用Qt Creator的介面編輯器也可以,只不過感覺Qt Designer更好用一點,因為可以隨時執行檢視你的介面效果而不用編譯整個專案輸出一個可執行程式再看看介面效果,這樣會影響效率。

介面設計你想介面是什麼樣就怎麼樣設計,拉控制元件,排版,設定大小,修改物件名等等,都在這上面做好,這些用程式寫的話會很麻煩,工作量也大。這上面的物件名很重要,因為在後面的程式碼實現中會用到,這個介面用到的控制元件還是挺多的,這裡也不一個一個講,我直接貼出來:

Qt串列埠通訊開發之Qt串列埠通訊模組QSerialPort開發完整例項(串列埠助手開發)

Qt串列埠通訊開發之Qt串列埠通訊模組QSerialPort開發完整例項(串列埠助手開發)

Qt串列埠通訊開發之Qt串列埠通訊模組QSerialPort開發完整例項(串列埠助手開發)

Qt串列埠通訊開發之Qt串列埠通訊模組QSerialPort開發完整例項(串列埠助手開發)

Qt串列埠通訊開發之Qt串列埠通訊模組QSerialPort開發完整例項(串列埠助手開發)

senderGB_1 - 5都是一樣的,改下數就行

Qt串列埠通訊開發之Qt串列埠通訊模組QSerialPort開發完整例項(串列埠助手開發)

Qt串列埠通訊開發之Qt串列埠通訊模組QSerialPort開發完整例項(串列埠助手開發)

當然,用你自己喜歡的命名也可以,後面程式改下名字就行。

二、程式碼實現

先貼程式碼

basictransceiver.h

#ifndef BASICTRANSCEIVER_H
#define BASICTRANSCEIVER_H

#include <QMainWindow>
#include "ui_basictransceiver.h"

class QTimer;
class SerialPortSetting;
class QSerialPort;
class QPushButton;

class BasicTransceiver : public QMainWindow,public Ui::BasicTransceiver
{
 Q_OBJECT

public:
 explicit BasicTransceiver(QWidget *parent = 0);

 ~BasicTransceiver();

 void StringToHex(QString str,QByteArray &senddata);

 char ConvertHexChar(char ch);

 void startAutoSend(QPushButton *sendButton);

 void setConnections();

 void writeHex(QTextEdit *textEdit);

 void writeChr(QTextEdit *textEdit);

 void resetCnt();

protected:
 void dragEnterEvent(QDragEnterEvent *event);

 void dropEvent(QDropEvent *event);

private slots:
 void checkAutoSendCB();

 void on_cleanButton_clicked();

 void on_receiveTextBrowser_textChanged();

 void setBaudRate();

 void setParity();

 void setDataBits();

 void setStopBits();

 void setFlowCtrl();

 void on_connectButton_toggled(bool checked);

 void setComLabel();

 void setBaudLabel();

 void writeToBuf();

 void enabledSendButton();

 void disabledSendButton();

 void enabledAutoSend();

 void disabledAutoButton();

 void resetAutoSendCB();

 void readMyCom();

 void checkAvailablePorts();

 void on_checkAPButton_clicked();

 void checkPort();

 void on_resetCntButton_clicked();

 void on_exitButton_clicked();

 bool saveAs();

 void open();

 //void about();

private:
 bool loadFile(const QString &fileName);

 bool readFile(const QString &fileName);

 bool saveFile(const QString &fileName);

 bool writeFile(const QString &fileName);

 QTimer *Timer_AS;//自動傳送定時器
 QTimer *Timer_UPDATE;
 QTimer *Timer_CP;//定時檢測串列埠是否存在
 SerialPortSetting *SPSetting;
 QSerialPort *mySerialPort;
 QSet<QString> portSet;
 QVector<int> iVec;
 QString senderFlag;
 QString readData;
 bool trashFlag = false;
 bool portIsOpen = false;
 int BaudCnt = 0;
 int ParityCnt = 0;
 int DataBitsCnt = 0;
 int StopBitsCnt = 0;
 int FlowCtrlCnt = 0;


};

#endif // BASICTRANSCEIVER_H

basictransceiver.cpp

#include "basictransceiver.h"
#include "serialportsetting.h"
#include "ui_basictransceiver.h"
#include "ui_serialportsetting.h"
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QDebug>
#include <QMessageBox>
#include <QStatusBar>
#include <QPushButton>
#include <QByteArray>
#include <QDataStream>
#include <QTimer>
#include <QRegExp>
#include <QRegExpValidator>
#include <QFile>
#include <QFileDialog>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QAction>

BasicTransceiver::BasicTransceiver(QWidget *parent) :
 QMainWindow(parent)
{
 setupUi(this);
 setFixedSize(1074,627);
 receiveTextBrowser->setAcceptDrops(false);//預設情況下,QTextEdit接受來自其他應用程式拖拽來的文字,把檔名顯示出來。
 senderTextEdit_1->setAcceptDrops(false);
 senderTextEdit_2->setAcceptDrops(false);
 senderTextEdit_3->setAcceptDrops(false);
 senderTextEdit_4->setAcceptDrops(false);
 senderTextEdit_5->setAcceptDrops(false);
 setAcceptDrops(true);//通過禁止QTextEdit控制元件的drop事件,允許主視窗得到drop事件

 connectButton->setIcon(QIcon(":/images/open.png"));
 cleanButton->setIcon(QIcon(":/images/empty_bin.png"));
 checkAPButton->setIcon(QIcon(":/images/find.png"));
 resetCntButton->setIcon(QIcon(":/images/to_zero.png"));
 exitButton->setIcon(QIcon(":/images/exit.png"));
 actionWrite_data->setIcon(QIcon(":/images/write.png"));
 actionRead_data->setIcon(QIcon(":/images/read.png"));
 actionChoose_file->setIcon(QIcon(":/images/select_file.png"));
 exitAction->setIcon(QIcon(":/images/exit.png"));
 actionAbout->setIcon(QIcon(":/images/about.png"));
 sendButton_1->setIcon(QIcon(":/images/send.png"));
 sendButton_2->setIcon(QIcon(":/images/send.png"));
 sendButton_3->setIcon(QIcon(":/images/send.png"));
 sendButton_4->setIcon(QIcon(":/images/send.png"));
 sendButton_5->setIcon(QIcon(":/images/send.png"));

 setConnections();
 emit checkAvailablePorts();

 Timer_CP = new QTimer(this);
 Timer_UPDATE = new QTimer(this);
 connect(Timer_UPDATE,SIGNAL(timeout()),this,SLOT(repaint()));
 Timer_UPDATE->start(2000);
 Timer_AS = new QTimer(this);
}

BasicTransceiver::~BasicTransceiver()
{

}

void BasicTransceiver::checkAutoSendCB()
{
 QObject *signalSender = sender();
 if ( signalSender->objectName() == "autoSendCB_1")
 {
  if (autoSendCB_1->isChecked())
  {
   intervalSB_1->setEnabled(false);
   autoSendCB_2->setEnabled(false);
   autoSendCB_3->setEnabled(false);
   autoSendCB_4->setEnabled(false);
   autoSendCB_5->setEnabled(false);
   startAutoSend(sendButton_1);
  } else if (!autoSendCB_1->isChecked()) {
   Timer_AS->stop();
   Timer_AS->disconnect();
   intervalSB_1->setEnabled(true);
   autoSendCB_2->setEnabled(true);
   autoSendCB_3->setEnabled(true);
   autoSendCB_4->setEnabled(true);
   autoSendCB_5->setEnabled(true);
   enabledSendButton();
  }
 } else if ( signalSender->objectName() == "autoSendCB_2") {
   if (autoSendCB_2->isChecked())
   {
    intervalSB_2->setEnabled(false);
    autoSendCB_1->setEnabled(false);
    autoSendCB_3->setEnabled(false);
    autoSendCB_4->setEnabled(false);
    autoSendCB_5->setEnabled(false);
    startAutoSend(sendButton_2);
   } else if (!autoSendCB_2->isChecked()) {
    Timer_AS->stop();
    Timer_AS->disconnect();
    intervalSB_2->setEnabled(true);
    autoSendCB_1->setEnabled(true);
    autoSendCB_3->setEnabled(true);
    autoSendCB_4->setEnabled(true);
    autoSendCB_5->setEnabled(true);
    enabledSendButton();
   }
  } else if ( signalSender->objectName() == "autoSendCB_3") {
   if (autoSendCB_3->isChecked())
   {
    intervalSB_3->setEnabled(false);
    autoSendCB_1->setEnabled(false);
    autoSendCB_2->setEnabled(false);
    autoSendCB_4->setEnabled(false);
    autoSendCB_5->setEnabled(false);
    startAutoSend(sendButton_3);
   } else if (!autoSendCB_3->isChecked()) {
    Timer_AS->stop();
    Timer_AS->disconnect();
    intervalSB_3->setEnabled(true);
    autoSendCB_1->setEnabled(true);
    autoSendCB_2->setEnabled(true);
    autoSendCB_4->setEnabled(true);
    autoSendCB_5->setEnabled(true);
    enabledSendButton();
   }
  } else if ( signalSender->objectName() == "autoSendCB_4") {
   if (autoSendCB_4->isChecked())
   {
    intervalSB_4->setEnabled(false);
    autoSendCB_1->setEnabled(false);
    autoSendCB_2->setEnabled(false);
    autoSendCB_3->setEnabled(false);
    autoSendCB_5->setEnabled(false);
    startAutoSend(sendButton_4);
   } else if (!autoSendCB_4->isChecked()) {
    Timer_AS->stop();
    Timer_AS->disconnect();
    intervalSB_4->setEnabled(true);
    autoSendCB_1->setEnabled(true);
    autoSendCB_2->setEnabled(true);
    autoSendCB_3->setEnabled(true);
    autoSendCB_5->setEnabled(true);
    enabledSendButton();
   }
  } else if ( signalSender->objectName() == "autoSendCB_5") {
   if (autoSendCB_5->isChecked())
   {
    intervalSB_5->setEnabled(false);
    autoSendCB_1->setEnabled(false);
    autoSendCB_2->setEnabled(false);
    autoSendCB_3->setEnabled(false);
    autoSendCB_4->setEnabled(false);
   startAutoSend(sendButton_5);
   } else if (!autoSendCB_5->isChecked()) {
    Timer_AS->stop();
    Timer_AS->disconnect();
    intervalSB_5->setEnabled(true);
    autoSendCB_1->setEnabled(true);
    autoSendCB_2->setEnabled(true);
    autoSendCB_3->setEnabled(true);
    autoSendCB_4->setEnabled(true);
    enabledSendButton();
   }
  }
 }

//清除接收區的內容
void BasicTransceiver::on_cleanButton_clicked()
{
 if (trashFlag == true) {
  receiveTextBrowser->clear();
  cleanButton->setIcon(QIcon(":/images/empty_bin.png"));
 }
}

void BasicTransceiver::on_receiveTextBrowser_textChanged()
{
 QString tempStr = receiveTextBrowser->toPlainText();
 if (!tempStr.isEmpty()) {
  trashFlag = true;
  if (autoClean->isChecked()){
   if (tempStr.size() >6200 ){
    receiveTextBrowser->clear();
    cleanButton->setIcon(QIcon(":/images/empty_bin.png"));
   }
  } else {
  cleanButton->setIcon(QIcon(":/images/clean.png"));
  }
 } else {
  trashFlag = false;
  cleanButton->setIcon(QIcon(":/images/empty_bin.png"));
 }
}


void BasicTransceiver::setBaudRate()
{
 if (portIsOpen) {
  if (BAUDCB->currentText() == "115200")
   mySerialPort->setBaudRate(QSerialPort::Baud115200);
  else if (BAUDCB->currentText() == "9600")
   mySerialPort->setBaudRate(QSerialPort::Baud9600);
  else if (BAUDCB->currentText() == "1200")
   mySerialPort->setBaudRate(QSerialPort::Baud1200);
  else if (BAUDCB->currentText() == "2400")
   mySerialPort->setBaudRate(QSerialPort::Baud2400);
  else if (BAUDCB->currentText() == "4800")
   mySerialPort->setBaudRate(QSerialPort::Baud4800);
  else if (BAUDCB->currentText() == "19200")
   mySerialPort->setBaudRate(QSerialPort::Baud19200);
  else if (BAUDCB->currentText() == "38400")
   mySerialPort->setBaudRate(QSerialPort::Baud38400);
  else if (BAUDCB->currentText() == "57600")
   mySerialPort->setBaudRate(QSerialPort::Baud57600);
  emit setBaudLabel();
  if (BaudCnt) {
   statusBar()->showMessage("BaudRate set successfully",2000);
  }
  ++BaudCnt;
 }
}

void BasicTransceiver::setParity()
{
 if (portIsOpen) {
  if (ParityCB->currentText() == QString::fromLocal8Bit("無校驗"))
   mySerialPort->setParity(QSerialPort::NoParity);
  else if (ParityCB->currentText() == QString::fromLocal8Bit("奇校驗"))
   mySerialPort->setParity(QSerialPort::OddParity);
  else if (ParityCB->currentText() == QString::fromLocal8Bit("偶校驗"))
   mySerialPort->setParity(QSerialPort::EvenParity);
  if (ParityCnt) {
   statusBar()->showMessage("Parity set successfully",2000);
  }
  ++ParityCnt;
 }
}

void BasicTransceiver::setDataBits()
{
 if (portIsOpen) {
  if (DataBitsCB->currentText() == "8")
   mySerialPort->setDataBits(QSerialPort::Data8);
  else if (DataBitsCB->currentText() == "7")
   mySerialPort->setDataBits(QSerialPort::Data7);
  else if (DataBitsCB->currentText() == "6")
   mySerialPort->setDataBits(QSerialPort::Data6);
  else if (DataBitsCB->currentText() == "5")
   mySerialPort->setDataBits(QSerialPort::Data5);
  if (DataBitsCnt) {
    statusBar()->showMessage("DataBits set successfully",2000);
  }
  ++DataBitsCnt;
 }
}

void BasicTransceiver::setStopBits()
{
 if (portIsOpen) {
  if (StopBitsCB->currentText() == "1")
   mySerialPort->setStopBits(QSerialPort::OneStop);
  else if (StopBitsCB->currentText() == "1.5")
   mySerialPort->setStopBits(QSerialPort::OneAndHalfStop);
  else if (StopBitsCB->currentText() == "2")
   mySerialPort->setStopBits(QSerialPort::TwoStop);
  if (StopBitsCnt) {
   statusBar()->showMessage("StopBits set successfully",2000);
  }
  ++StopBitsCnt;
 }
}

void BasicTransceiver::setFlowCtrl()
{
 if (portIsOpen) {
  if (FlowCtrlCB->currentText() == "off")
   mySerialPort->setFlowControl(QSerialPort::NoFlowControl);
  else if (FlowCtrlCB->currentText() == "hardware")
   mySerialPort->setFlowControl(QSerialPort::HardwareControl);
  else if (FlowCtrlCB->currentText() == "xonxoff")
   mySerialPort->setFlowControl(QSerialPort::SoftwareControl);
  if (FlowCtrlCnt) {
   statusBar()->showMessage("FlowCtrl set successfully",2000);
  }
  ++FlowCtrlCnt;
 }
}

void BasicTransceiver::resetCnt()
{
 BaudCnt = 0;
 ParityCnt = 0;
 DataBitsCnt = 0;
 StopBitsCnt = 0;
 FlowCtrlCnt = 0;
}

//開啟和關閉串列埠
void BasicTransceiver::on_connectButton_toggled(bool checked)
{
 if (checked == true) {
  mySerialPort = new QSerialPort(this);
  QString tempStr = COMCB->currentText();
  tempStr.remove(" avail",Qt::CaseSensitive);
  mySerialPort->setPortName(tempStr);
  if (mySerialPort->open(QIODevice::ReadWrite)) {
    portIsOpen = true;
    emit setBaudRate();
    emit setParity();
    emit setDataBits();
    emit setStopBits();
    emit setFlowCtrl();
    statusBar()->showMessage(mySerialPort->portName() + " is opened",2000);
    emit setComLabel();
    emit enabledSendButton();
    emit enabledAutoSend();
    COMCB->setEnabled(false);
    connect(Timer_CP,SLOT(checkPort()));
    Timer_CP->start(1000);
    connect(mySerialPort,SIGNAL(readyRead()),SLOT(readMyCom()));
    connectButton->setText(QString::fromLocal8Bit("關閉連線"));
    connectButton->setIcon(QIcon(":/images/close.png"));
   } else {
    QMessageBox::warning(this,QString::fromLocal8Bit("串列埠開啟失敗"),QString::fromLocal8Bit("串列埠不存在或本串列埠"
                        "已經被佔用,請重試!"),QMessageBox::Cancel);
    connectButton->setChecked(false);
    return;
   }
 } else if (checked == false) {
   if (Timer_AS->isActive()) {
    Timer_AS->stop();
    emit resetAutoSendCB();
   }
   if (Timer_CP->isActive()) Timer_CP->stop();
   Timer_CP->disconnect();
   if (mySerialPort->isOpen()) mySerialPort->close();
   emit disabledSendButton();
   emit disabledAutoButton();
   emit setComLabel();
   emit setBaudLabel();
   resetCnt();
   COMCB->setEnabled(true);
   connectButton->setText(QString::fromLocal8Bit("開啟連線"));
   connectButton->setIcon(QIcon(":/images/open.png"));
   portIsOpen = false;
 }
}

//設定顯示串列埠號和波特率的Label
void BasicTransceiver::setComLabel()
{
 if (mySerialPort->isOpen()) {
  comLabel->setText(QString(mySerialPort->portName()));
 } else if (!mySerialPort->isOpen()) {
  comLabel->setText(QString::fromLocal8Bit("COM:#"));
 }
}

void BasicTransceiver::setBaudLabel()
{
 if (mySerialPort->isOpen()) {
  int i_baud = mySerialPort->baudRate();
  QString s_baud;
  baudLabel->setText(s_baud.setNum(i_baud));
 } else if (!mySerialPort->isOpen()) {
  baudLabel->setText(QString::fromLocal8Bit("BAUD:#"));
 }
}

void BasicTransceiver::writeToBuf()
{
 QObject *signalSender = sender();
 if (signalSender->objectName() == "sendButton_1") {
  if (hexRB_1->isChecked()) {
   writeHex(senderTextEdit_1);
  } else {
   writeChr(senderTextEdit_1);
  }
 } else if (signalSender->objectName() == "sendButton_2") {
  if (hexRB_2->isChecked()) {
   writeHex(senderTextEdit_2);
  } else {
   writeChr(senderTextEdit_2);
  }
 } else if (signalSender->objectName() == "sendButton_3") {
  if (hexRB_3->isChecked()) {
   writeHex(senderTextEdit_3);
  } else {
   writeChr(senderTextEdit_3);
  }
 } else if (signalSender->objectName() == "sendButton_4") {
  if (hexRB_4->isChecked()) {
   writeHex(senderTextEdit_4);
  } else {
   writeChr(senderTextEdit_4);
  }
 } else if (signalSender->objectName() == "sendButton_5") {
  if (hexRB_5->isChecked()) {
   writeHex(senderTextEdit_5);
  } else {
   writeChr(senderTextEdit_5);
  }
 }
}

void BasicTransceiver::writeHex(QTextEdit *textEdit)
{
 QString dataStr = textEdit->toPlainText();
 //如果傳送的資料個數為奇數的,則在前面最後落單的字元前新增一個字元0
 if (dataStr.length() % 2){
  dataStr.insert(dataStr.length()-1,'0');
 }
 QByteArray sendData;
 StringToHex(dataStr,sendData);
 mySerialPort->write(sendData);
 RxLCD->display(RxLCD->value() + sendData.size());
}

void BasicTransceiver::writeChr(QTextEdit *textEdit)
{
 QByteArray sendData = textEdit->toPlainText().toUtf8();
 if (!sendData.isEmpty() && !sendData.isNull()) {
  mySerialPort->write(sendData);
 }
 RxLCD->display(RxLCD->value() + sendData.size());
}

void BasicTransceiver::StringToHex(QString str,QByteArray &senddata) //字串轉換為十六進位制資料0-F
{
 int hexdata,lowhexdata;
 int hexdatalen = 0;
 int len = str.length();
 senddata.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;
  senddata[hexdatalen] = (char)hexdata;
  ++hexdatalen;
 }
 senddata.resize(hexdatalen);
}

char BasicTransceiver::ConvertHexChar(char ch)
{
 if ((ch >= '0') && (ch <= '9'))
  return ch - 0x30;
 else if ((ch >= 'A') && (ch <= 'F'))
  return ch - 'A' + 10;
 else if ((ch >= 'a') && (ch <= 'f'))
  return ch - 'a' + 10;
 else return ch - ch;
}

void BasicTransceiver::enabledSendButton()
{
 sendButton_1->setEnabled(true);
 sendButton_2->setEnabled(true);
 sendButton_3->setEnabled(true);
 sendButton_4->setEnabled(true);
 sendButton_5->setEnabled(true);
}

void BasicTransceiver::disabledSendButton()
{
 sendButton_1->setEnabled(false);
 sendButton_2->setEnabled(false);
 sendButton_3->setEnabled(false);
 sendButton_4->setEnabled(false);
 sendButton_5->setEnabled(false);
}

void BasicTransceiver::startAutoSend(QPushButton *sendButton)
{
 connect(Timer_AS,sendButton,SIGNAL(clicked()));
 QString interval;
 if (sendButton->objectName() == "sendButton_1") {
  disabledSendButton();
  Timer_AS->start(intervalSB_1->value());
  statusBar()->showMessage(QString::fromLocal8Bit("每 ") + interval.setNum(intervalSB_1->value())+ QString::fromLocal8Bit("ms 自動傳送一次"),2000);
 } else if (sendButton->objectName() == "sendButton_2") {
  disabledSendButton();
  Timer_AS->start(intervalSB_2->value());
  statusBar()->showMessage(QString::fromLocal8Bit("每 ") + interval.setNum(intervalSB_2->value())+ QString::fromLocal8Bit("ms 自動傳送一次"),2000);
 } else if (sendButton->objectName() == "sendButton_3") {
  disabledSendButton();
  Timer_AS->start(intervalSB_3->value());
  statusBar()->showMessage(QString::fromLocal8Bit("每 ") + interval.setNum(intervalSB_3->value())+ QString::fromLocal8Bit("ms 自動傳送一次"),2000);
 } else if (sendButton->objectName() == "sendButton_4") {
  disabledSendButton();
  Timer_AS->start(intervalSB_4->value());
  statusBar()->showMessage(QString::fromLocal8Bit("每 ") + interval.setNum(intervalSB_4->value())+ QString::fromLocal8Bit("ms 自動傳送一次"),2000);
 } else if (sendButton->objectName() == "sendButton_5") {
  disabledSendButton();
  Timer_AS->start(intervalSB_5->value());
  statusBar()->showMessage(QString::fromLocal8Bit("每 ") + interval.setNum(intervalSB_5->value())+ QString::fromLocal8Bit("ms 自動傳送一次"),2000);
 }
}

void BasicTransceiver::setConnections()
{
 connect(autoSendCB_1,SIGNAL(stateChanged(int)),SLOT(checkAutoSendCB()));
 connect(autoSendCB_2,SLOT(checkAutoSendCB()));
 connect(autoSendCB_3,SLOT(checkAutoSendCB()));
 connect(autoSendCB_4,SLOT(checkAutoSendCB()));
 connect(autoSendCB_5,SLOT(checkAutoSendCB()));

 connect(actionWrite_data,SIGNAL(triggered()),SLOT(saveAs()));
 connect(actionRead_data,SLOT(open()));
 connect(actionChoose_file,SLOT(open()));
 connect(exitAction,qApp,SLOT(quit()));
 connect(actionAbout,SLOT(aboutQt()));

 connect(sendButton_1,SIGNAL(clicked()),SLOT(writeToBuf()));
 connect(sendButton_2,SLOT(writeToBuf()));
 connect(sendButton_3,SLOT(writeToBuf()));
 connect(sendButton_4,SLOT(writeToBuf()));
 connect(sendButton_5,SLOT(writeToBuf()));

 connect(BAUDCB,SIGNAL(currentIndexChanged(int)),SLOT(setBaudRate()));
 connect(ParityCB,SLOT(setParity()));
 connect(DataBitsCB,SLOT(setDataBits()));
 connect(StopBitsCB,SLOT(setStopBits()));
 connect(FlowCtrlCB,SLOT(setFlowCtrl()));
}

void BasicTransceiver::enabledAutoSend()
{
 autoSendCB_1->setEnabled(true);
 autoSendCB_2->setEnabled(true);
 autoSendCB_3->setEnabled(true);
 autoSendCB_4->setEnabled(true);
 autoSendCB_5->setEnabled(true);
}

void BasicTransceiver::disabledAutoButton()
{
 autoSendCB_1->setEnabled(false);
 autoSendCB_2->setEnabled(false);
 autoSendCB_3->setEnabled(false);
 autoSendCB_4->setEnabled(false);
 autoSendCB_5->setEnabled(false);
}



void BasicTransceiver::resetAutoSendCB()
{
 autoSendCB_1->setChecked(false);
 autoSendCB_2->setChecked(false);
 autoSendCB_3->setChecked(false);
 autoSendCB_4->setChecked(false);
 autoSendCB_5->setChecked(false);
}

void BasicTransceiver::readMyCom()
{
 QByteArray temp = mySerialPort->readAll();
 QString buf;

 if (actionAlways_show->isChecked()) {
  if(!temp.isEmpty()){
    if(chrReceive->isChecked()){
     buf = temp;
    }else if(hexReceive->isChecked()){
     for(int i = 0; i < temp.count(); i++){
      QString s;
      s.sprintf("0x%02x,",(unsigned char)temp.at(i));
      buf += s;
     }
    }
   receiveTextBrowser->setText(receiveTextBrowser->document()->toPlainText() + buf);
   receiveTextBrowser->moveCursor(QTextCursor::End);


   //ui->statusBar->showMessage(tr("成功讀取%1位元組資料").arg(temp.size()));
  }
 }
 TxLCD->display(TxLCD->value() + temp.size());
}

//檢測可用串列埠並在可用串列埠號後面加上可用標誌
void BasicTransceiver::checkAvailablePorts()
{//找不到存在串列埠是不會進入到foreach內部的。。。存在不一定可用
 foreach ( const QSerialPortInfo &Info,QSerialPortInfo::availablePorts()) {
  QSerialPort availablePort;
  availablePort.setPortName(Info.portName());
  if (availablePort.open(QIODevice::ReadWrite)) {
   int index = COMCB->findText(Info.portName());
   COMCB->setItemText(index,Info.portName() + " avail");
   COMCB->setCurrentIndex(index);
   iVec.push_back(index);//將修改了內容的項索引新增到容器中
   checkAPButton->setIcon(QIcon(":/images/find_it.png"));
   availablePort.close();
   }
 }
 if (iVec.size() == 0) {checkAPButton->setIcon(QIcon(":/images/find.png"));}
 QString availPortCnt;
 statusBar()->showMessage(availPortCnt.setNum(iVec.size()) + " available ports",2000);
}
//將選擇串列埠號的checkBox重置並重新檢測可用串列埠
void BasicTransceiver::on_checkAPButton_clicked()
{
 if (!iVec.isEmpty()) {
  for (int i = 0; i != iVec.size(); ++i) {
   QString tempStr;
   COMCB->setItemText(iVec[i],QString("COM") +
               tempStr.setNum(iVec[i]));
  }
  COMCB->setCurrentIndex(0);
  iVec.clear();
 }
 emit checkAvailablePorts();
}

void BasicTransceiver::checkPort()
{
 QSet<QString> portSet;
 foreach ( const QSerialPortInfo &Info,QSerialPortInfo::availablePorts()) {
  portSet.insert(Info.portName());
 }
 if (portSet.find(mySerialPort->portName()) == portSet.end()) {
  QMessageBox::warning(this,QString::fromLocal8Bit("Application error"),QString::fromLocal8Bit("Fail with the following error : \n串列埠訪問失敗\n\nPort:%1")
            .arg(mySerialPort->portName()),QMessageBox::Close);
  emit on_connectButton_toggled(false);
 }
}

void BasicTransceiver::on_resetCntButton_clicked()
{
 RxLCD->display(0);
 TxLCD->display(0);
}

void BasicTransceiver::on_exitButton_clicked()
{
 qApp->quit();
}
//另存為
bool BasicTransceiver::saveAs()
{
 QString fileName = QFileDialog::getSaveFileName(this,tr("Save Data"),".",tr("Text File (*.txt)"));
 if (fileName.isEmpty()) {
  return false;
 }
 return saveFile(fileName);
}
//儲存檔案
bool BasicTransceiver::saveFile(const QString &fileName)
{
 if (!writeFile(fileName)) {
  statusBar()->showMessage(tr("Saving canceled"),2000);
  return false;
 }
 statusBar()->showMessage(tr("Data saved"),2000);
 return true;
}

bool BasicTransceiver::writeFile(const QString &fileName)
{
 QFile file(fileName);
 if (!file.open(QIODevice::WriteOnly | QFile::Text)) {
  QMessageBox::warning(this,tr("Cannot write file %1 : \n%2")
              .arg(file.fileName())
              .arg(file.errorString()));
  return false;
 }
 QTextStream out(&file);
 out << receiveTextBrowser->toPlainText();
 return true;
}

//開啟檔案的函式
void BasicTransceiver::open()
{
 QString fileName = QFileDialog::getOpenFileName(this,tr("Choose Text File"),tr("Text File (*.txt)"));
 if (!fileName.isEmpty()) {
  loadFile(fileName);
 }
}
//載入檔案
bool BasicTransceiver::loadFile(const QString &fileName)
{
 if (!readFile(fileName)) {
   statusBar()->showMessage(tr("Loading canceled"),2000);
   return false;
  }
  statusBar()->showMessage(tr("Data loaded"),2000);
  return true;
}
//讀取檔案
bool BasicTransceiver::readFile(const QString &fileName)
{
 QFile file(fileName);
  if (!file.open(QIODevice::ReadOnly)) {
   QMessageBox::warning(this,tr("Read failed"),tr("Cannot read file %1 : \n%2.")
              .arg(file.fileName())
              .arg(file.errorString()));
   return false;
  }
  QTextStream in(&file);
  QObject *signalSender = sender();
  if (signalSender->objectName() == "actionRead_data"){
   receiveTextBrowser->setText(in.readAll());
  } else if (signalSender->objectName() == "actionChoose_file") {
   senderTextEdit_1->setText(in.readAll());
  }
  return true;
}

void BasicTransceiver::dragEnterEvent(QDragEnterEvent *event)
{
 if (event->mimeData()->hasFormat("text/uri-list"))
   event->acceptProposedAction();
}

void BasicTransceiver::dropEvent(QDropEvent *event)
{
 QList<QUrl> urls = event->mimeData()->urls();
  if (urls.isEmpty())
   return;
  QString fileName = urls.first().toLocalFile();
  if (fileName.isEmpty()){
   return;
  }
  loadFile(fileName);
}

程式完全是面向物件的,每個功能都是用相應函式實現的,這也提高了函式的重用性。

本文是一個完整的Qt串列埠通訊模組QSerialPort開發完整例項,感興趣的可以細細閱讀原始碼內容,更多關於Qt串列埠通訊知識請檢視下面的相關連結