溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Qt串口通信開(kāi)發(fā)之Qt串口通信模塊QSerialPort開(kāi)發(fā)完整實(shí)例(串口助手開(kāi)發(fā))

發(fā)布時(shí)間:2020-08-22 12:06:41 來(lái)源:腳本之家 閱讀:345 作者:imkelt 欄目:編程語(yǔ)言

之前自己寫(xiě)了用于上位機(jī)做基本收發(fā)的界面,獨(dú)立出來(lái)相當(dāng)于一個(gè)串口助手,先貼圖:

Qt串口通信開(kāi)發(fā)之Qt串口通信模塊QSerialPort開(kāi)發(fā)完整實(shí)例(串口助手開(kāi)發(fā))

功能作為串口助手來(lái)說(shuō)還算完善,五個(gè)發(fā)送槽,一個(gè)接收槽,可以檢測(cè)可用串口并加上相關(guān)標(biāo)志,串口設(shè)置,記數(shù)功能,還有菜單欄上的文件操作和一些選擇功能。

下面說(shuō)一說(shuō)這個(gè)項(xiàng)目:

做這個(gè)串口助手分為兩步,第一步是設(shè)計(jì)界面,第二部是功能的代碼實(shí)現(xiàn)。

一、界面設(shè)計(jì)

界面設(shè)計(jì)用Qt Designer,當(dāng)然用Qt Creator的界面編輯器也可以,只不過(guò)感覺(jué)Qt Designer更好用一點(diǎn),因?yàn)榭梢噪S時(shí)運(yùn)行查看你的界面效果而不用編譯整個(gè)項(xiàng)目輸出一個(gè)可執(zhí)行程序再看看界面效果,這樣會(huì)影響效率。

界面設(shè)計(jì)你想界面是什么樣就怎么樣設(shè)計(jì),拉控件,排版,設(shè)置大小,修改對(duì)象名等等,都在這上面做好,這些用程序?qū)懙脑挄?huì)很麻煩,工作量也大。這上面的對(duì)象名很重要,因?yàn)樵诤竺娴拇a實(shí)現(xiàn)中會(huì)用到,這個(gè)界面用到的控件還是挺多的,這里也不一個(gè)一個(gè)講,我直接貼出來(lái):

Qt串口通信開(kāi)發(fā)之Qt串口通信模塊QSerialPort開(kāi)發(fā)完整實(shí)例(串口助手開(kāi)發(fā))

Qt串口通信開(kāi)發(fā)之Qt串口通信模塊QSerialPort開(kāi)發(fā)完整實(shí)例(串口助手開(kāi)發(fā))

Qt串口通信開(kāi)發(fā)之Qt串口通信模塊QSerialPort開(kāi)發(fā)完整實(shí)例(串口助手開(kāi)發(fā))

Qt串口通信開(kāi)發(fā)之Qt串口通信模塊QSerialPort開(kāi)發(fā)完整實(shí)例(串口助手開(kāi)發(fā))

Qt串口通信開(kāi)發(fā)之Qt串口通信模塊QSerialPort開(kāi)發(fā)完整實(shí)例(串口助手開(kāi)發(fā))

senderGB_1 - 5都是一樣的,改下數(shù)就行

Qt串口通信開(kāi)發(fā)之Qt串口通信模塊QSerialPort開(kāi)發(fā)完整實(shí)例(串口助手開(kāi)發(fā))

Qt串口通信開(kāi)發(fā)之Qt串口通信模塊QSerialPort開(kāi)發(fā)完整實(shí)例(串口助手開(kāi)發(fā))

當(dāng)然,用你自己喜歡的命名也可以,后面程序改下名字就行。

二、代碼實(shí)現(xiàn)

先貼代碼

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;//自動(dòng)發(fā)送定時(shí)器
 QTimer *Timer_UPDATE;
 QTimer *Timer_CP;//定時(shí)檢測(cè)串口是否存在
 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接受來(lái)自其他應(yīng)用程序拖拽來(lái)的文本,把文件名顯示出來(lái)。
 senderTextEdit_1->setAcceptDrops(false);
 senderTextEdit_2->setAcceptDrops(false);
 senderTextEdit_3->setAcceptDrops(false);
 senderTextEdit_4->setAcceptDrops(false);
 senderTextEdit_5->setAcceptDrops(false);
 setAcceptDrops(true);//通過(guò)禁止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();
   }
  }
 }

//清除接收區(qū)的內(nèi)容
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("無(wú)校驗(yàn)"))
   mySerialPort->setParity(QSerialPort::NoParity);
  else if (ParityCB->currentText() == QString::fromLocal8Bit("奇校驗(yàn)"))
   mySerialPort->setParity(QSerialPort::OddParity);
  else if (ParityCB->currentText() == QString::fromLocal8Bit("偶校驗(yàn)"))
   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;
}

//打開(kāi)和關(guān)閉串口
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, SIGNAL(timeout()), this, SLOT(checkPort()));
    Timer_CP->start(1000);
    connect(mySerialPort, SIGNAL(readyRead()), this, SLOT(readMyCom()));
    connectButton->setText(QString::fromLocal8Bit("關(guān)閉連接"));
    connectButton->setIcon(QIcon(":/images/close.png"));
   } else {
    QMessageBox::warning(this,
              QString::fromLocal8Bit("串口打開(kāi)失敗"),
              QString::fromLocal8Bit("串口不存在或本串口"
                        "已經(jīng)被占用,請(qǐng)重試!"),
              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("打開(kāi)連接"));
   connectButton->setIcon(QIcon(":/images/open.png"));
   portIsOpen = false;
 }
}

//設(shè)置顯示串口號(hào)和波特率的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();
 //如果發(fā)送的數(shù)據(jù)個(gè)數(shù)為奇數(shù)的,則在前面最后落單的字符前添加一個(gè)字符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) //字符串轉(zhuǎn)換為十六進(jìn)制數(shù)據(jù)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, SIGNAL(timeout()), 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 自動(dòng)發(fā)送一次") , 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 自動(dòng)發(fā)送一次") , 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 自動(dòng)發(fā)送一次") , 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 自動(dòng)發(fā)送一次") , 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 自動(dòng)發(fā)送一次") , 2000);
 }
}

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

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

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

 connect(BAUDCB, SIGNAL(currentIndexChanged(int)), this, SLOT(setBaudRate()));
 connect(ParityCB, SIGNAL(currentIndexChanged(int)), this, SLOT(setParity()));
 connect(DataBitsCB, SIGNAL(currentIndexChanged(int)), this, SLOT(setDataBits()));
 connect(StopBitsCB, SIGNAL(currentIndexChanged(int)), this, SLOT(setStopBits()));
 connect(FlowCtrlCB, SIGNAL(currentIndexChanged(int)), this, 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字節(jié)數(shù)據(jù)").arg(temp.size()));
  }
 }
 TxLCD->display(TxLCD->value() + temp.size());
}

//檢測(cè)可用串口并在可用串口號(hào)后面加上可用標(biāo)志
void BasicTransceiver::checkAvailablePorts()
{//找不到存在串口是不會(huì)進(jìn)入到foreach內(nèi)部的。。。存在不一定可用
 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);//將修改了內(nèi)容的項(xiàng)索引添加到容器中
   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);
}
//將選擇串口號(hào)的checkBox重置并重新檢測(cè)可用串口
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串口訪問(wè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("Save Data"),
              tr("Cannot write file %1 : \n%2")
              .arg(file.fileName())
              .arg(file.errorString()));
  return false;
 }
 QTextStream out(&file);
 out << receiveTextBrowser->toPlainText();
 return true;
}

//打開(kāi)文件的函數(shù)
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);
}

程序完全是面向?qū)ο蟮?,每個(gè)功能都是用相應(yīng)函數(shù)實(shí)現(xiàn)的,這也提高了函數(shù)的重用性。

本文是一個(gè)完整的Qt串口通信模塊QSerialPort開(kāi)發(fā)完整實(shí)例,感興趣的可以細(xì)細(xì)閱讀源碼內(nèi)容,更多關(guān)于Qt串口通信知識(shí)請(qǐng)查看下面的相關(guān)鏈接

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI