当前位置: 首页 > news >正文

QT - 串口QserialPort应用

https://doc.qt.io/qt-5.9/qserialport.html         //文档

使用该模块需要在pro文件中添加:QT += serialport 

主要使用两个类:QSerialPort (#include<QSerialPort>)和QSerialPortInfo (#include<QSerialPortInfo>)

获取串口信息:QserialPortInfo

QSerialPortInfo类提供已存在串口设备的信息。使用QSerialPortInfo类的静态成员函数生成QSerialPortInfo对象的链表。链表中的每个QSerialPortInfo对象代表一个串口,每个串口可以使用端口名、系统定位、描述、制造商查询。QSerialPortInfo类对象也可以用做QSerialPort类的setPort()成员函数的参数。

QSerialPortInfo类成员函数

//构造函数

QSerialPortInfo()

QSerialPortInfo(const QSerialPort &port)

QSerialPortInfo(const QString &name)

QSerialPortInfo(const QSerialPortInfo &other)

//析构函数

~QSerialPortInfo()

//返回当前系统可用串口的链表

[static] QList<QSerialPortInfo> QSerialPortInfo::availablePorts()

//如果串口可用,返回串口的描述信息

QString QSerialPortInfo::description() const

//如果有一个合法的16位生产码,返回true

bool QSerialPortInfo::hasProductIdentifier() const

//如果有一个合法的16位制造商编码,返回true

bool QSerialPortInfo::hasVendorIdentifier() const

//如果串口当前正忙,返回true

bool QSerialPortInfo::isBusy() const

//如果串口可用,返回串口的制造商的名字

QString QSerialPortInfo::manufacturer() const

//返回串口的名字

QString QSerialPortInfo::portName() const

//如果串口可用,返回串口的16位的生产编码

quint16 QSerialPortInfo::productIdentifier() const

//如果串口可用,返回串口的序列号

QString QSerialPortInfo::serialNumber() const

//返回目标平台支持的可用的标准波特率的链表

[static] QList<qint32> QSerialPortInfo::standardBaudRates()

//使用other交换QSerialPortInfo对象

void QSerialPortInfo::swap(QSerialPortInfo &other)

//返回串口的系统位置

QString QSerialPortInfo::systemLocation() const

//如果串口可用,返回16位的制造商编码

quint16 QSerialPortInfo::vendorIdentifier() const

程序示例

#include "widget.h"

#include <QDebug>

#include <QList>

#include <QtSerialPort/QSerialPortInfo>

Widget::Widget(QWidget *parent)

    : QWidget(parent)

{

    //获取当前系统下所有可以用的串口

    QList<QSerialPortInfo> serialPortInfo = QSerialPortInfo::availablePorts();

    qDebug() << "串口的个数: " << serialPortInfo.count();

    //显示目标串口支持的波特率列表

    QList<qint32> baudRates = QSerialPortInfo::standardBaudRates();

    qDebug() << baudRates;

    qDebug() << "串口的描述:" << serialPortInfo.at(0).description();

    qDebug() << "hasProductIdentifier(): " << serialPortInfo.at(0).hasProductIdentifier();

    qDebug() << "hasVendorIdentifier(): " << serialPortInfo.at(0).hasVendorIdentifier();

    qDebug() << "isBusy: " << serialPortInfo.at(0).isBusy();

    qDebug() << "manufacturer: " << serialPortInfo.at(0).manufacturer();

    qDebug() << "portName: " << serialPortInfo.at(0).portName();

    qDebug() << "productIdentifier: " << serialPortInfo.at(0).productIdentifier();

    qDebug() << "serialNumber: " << serialPortInfo.at(0).serialNumber();

    qDebug() << "vendorIdentifier: " << serialPortInfo.at(0).vendorIdentifier();

    qDebug() << "systemLocation: " << serialPortInfo.at(0).systemLocation();

}

Widget::~Widget()

{

}

QIODevice

QIODevice用于对输入输出设备进行管理。输入设备有两种类型,一种是随机访问设备(Random-accessdevices),如文件、缓冲区等;另一种是时序设备(Sequential device),如网络、进程等。可以通过isSequential()函数分辨设备是哪种类型的。

  OpenMode

返回类型

函数

说明

OpenMode

openMode() const

QIODevice::OpenMode

void [protected]

setOpenMode(OpenMode openMode)

bool

isOpen() const

QIODevice::NotOpen

bool

isReadable() const

QIODevice::ReadOnly

bool

isWritable() const

QIODevice::WriteOnly

bool

isTextModeEnabled() const

QIODevice::Text

void

setTextModeEnabled(bool enabled)

QIODevice::Text

bool [virtual]

isSequential() const

打开关闭设备

返回类型

函数

说明

bool [virtual]

open(OpenMode mode)

bool

isOpen() const

void [virtual]

close()

void [signal]

aboutToClose()

Bool [virtual]

reset()

重打开设备。

不适用于QIODevice::Text类设备。

数据读写操作及控制

输入函数

回类型

函数

说明

bool [virtual]

waitForReadyRead(int msecs)

等待可读

void [signal]

readyRead()

中断式可读

qint64 [virtual]

bytesAvailable()  const

查询式可读

qint64 [protected]

[pure virtual]

readData(char* data, qint64 maxSize)

需要在继承类重实现的读函数

qint64 [protected]

[pure virtual]

readData(char * data, qint64 maxSize)

需要在继承类重实现读函数

qint64 [protected]

[pure virtual]

readData(char * data, qint64 maxSize)

需要在继承类重实现的读函数

qint64 [protected]

[pure virtual]

readData(char * data, qint64 maxSize)

需要在继承类重实现的读函数

qint64 [protected]

[pure virtual]

readData(char* data, qint64 maxSize)

需要在继承类重实现的读函数

qint64 [protected]

[pure virtual]

readData(char* data, qint64 maxSize)

需要在继承类重实现的读函数

qint64 [protected]

[pure virtual]

readData(char* data, qint64 maxSize)

需要在继承类重实现的读函数

qint64 [virtual] [protected]

readLineData(char* data, qint64 maxSize)

可以在继承类重实现的读行函数

qint64

readLine(char * data, qint64 maxSize)

读行(maxSize包括行结束字符)

QByteArray

readLine(qint64 maxSize = 0)

读行

bool

getChar(char * c)

char

void

ungetChar(char c)

undo char

void [signal]

readChannelFinished()

输入通道结束。

但此时可能仍有数据可读。

输出函数

返回类型

函数

说明

bool [virtual]

waitForBytesWritten(int msecs)

等待已写

void [signal]

bytesWritten(qint64 bytes)

中断式已写

qint64 [virtual]

bytesToWrite() const

查询式写完

qint64 [protected]

[pure virtual]

writeData(const char* data,qint64 maxSize)

需要在继承类重实现的

写函数

qint64

write(const char * data, qint64 maxSize)

qint64

write(const char * data)

qint64

write(const QByteArray & byteArray)

bool

putChar(char c)

char

isSequential()不同有区别的函数

返回类型

函数

说明

qint64 [virtual]

pos() const

bool [virtual]

seek(qint64 pos)

qint64 [virtual]

size() const

随机访问设备为区域大小,时序设备为bytesAvailable()

其他函数

返回类型

函数

说明

bool [virtual]

atEnd() const

QString

errorString() const

void [protected]

setErrorString(const QString & str)

​​​​​​​串口IO操作:QserialPort

设置好端口后,可以使用open()函数以只读、只写或读写的模式打开使用。

注意,串口使用独占方式打开。使用close()函数关闭串口并且取消IO操作。

串口成功打开后,QSerialPort会尝试确定串口的当前配置并初始化。可以使用setBaudRate()setDataBits()setParity()setStopBits()setFlowControl()函数重新配置端口设置。

有一对名为QSerialPort::dataTerminalReady、QSerialPort::requestToSend的属性

QSerialPort提供了中止正在调用线程直到信号触发的一系列函数。这些函数用于阻塞串口。

waitForReadyRead():阻塞调用,直到有新的数据可读

waitForBytesWritten():阻塞调用,直到数据以及写入串口

阻塞串口编程与非阻塞串口编程完全不同。阻塞串口不会要求时间循环并且通常会简化代码。然而,在GUI程序中,为了避免冻结用户界面,阻塞串口编程只能用于非GUI线程。

QSerialPort也能使用QTextStream和QDataStream的流操作符。在试图使用流操作符>>读时,需要确保有足够可用的数据。

Qt串口通信模块QSerialPort类成员函数​​​​​​​

//构造函数

QSerialPort::QSerialPort(QObject *parent = Q_NULLPTR)

QSerialPort::QSerialPort(const QString &name, QObject *parent = Q_NULLPTR)

QSerialPort::QSerialPort(const QSerialPortInfo &serialPortInfo, QObject *parent = Q_NULLPTR)

//如果当前没有数据可读,返回true

[virtual] bool QSerialPort::atEnd() const

//波特率改变后,信号触发

[signal] void QSerialPort::baudRateChanged(qint32 baudRate, QSerialPort::Directions directions)

//返回可读数据的字节数

[virtual] qint64 QSerialPort::bytesAvailable() const

//返回可写数据的字节数

[virtual] qint64 QSerialPort::bytesToWrite() const

//关闭串口

[virtual] void QSerialPort::close()

//设置串口端口信息为serialPortInfo

void QSerialPort::setPort(const QSerialPortInfo &serialPortInfo)

//设置串口名为name

void QSerialPort::setPortName(const QString &name)

qint32     baudRate(QSerialPort::Directions directions = AllDirections) const

bool        clear(QSerialPort::Directions directions = AllDirections)

void         clearError()

QSerialPort::DataBits  dataBits()    const

QSerialPort::SerialPortError error()   const

QSerialPort::FlowControl     flowControl()   const

bool    flush()

QSerialPort::Handle   handle() const

Bool   isBreakEnabled() const

bool  isDataTerminalReady()

bool    isRequestToSend()

QSerialPort::Parity  parity() const

QSerialPort::PinoutSignals   pinoutSignals()

QString  portName() const

qint64    readBufferSize() const

bool   setBaudRate(qint32 baudRate, QSerialPort::Directions directions = AllDirections)

bool   setBreakEnabled(bool set = true)

bool  setDataBits(QSerialPort::DataBits dataBits)

bool   setDataTerminalReady(bool set)

bool   setFlowControl(QSerialPort::FlowControl flowControl)

bool   setParity(QSerialPort::Parity parity)

void    setPort(const QSerialPortInfo &serialPortInfo)

void    setPortName(const QString &name)

void    setReadBufferSize(qint64 size)

bool   setRequestToSend(bool set)

bool   setStopBits(QSerialPort::StopBits stopBits)

QSerialPort::StopBits  stopBits()  const

重新实现的公共函数

virtual qint64  bytesAvailable() const override

virtual qint64  bytesToWrite() const override

virtual bool     canReadLine() const override

virtual void      close() override

virtual bool      isSequential() const override

virtual bool      open(QIODeviceBase::OpenMode mode) override

virtual bool      waitForBytesWritten(int msecs = 30000) override

virtual bool      waitForReadyRead(int msecs = 30000) override

Signals

void baudRateChanged(qint32 baudRate, QSerialPort::Directions directions)

void breakEnabledChanged(bool set)

void dataBitsChanged(QSerialPort::DataBits dataBits)

void dataTerminalReadyChanged(bool set)

void errorOccurred(QSerialPort::SerialPortError error)

void flowControlChanged(QSerialPort::FlowControl flow)

void parityChanged(QSerialPort::Parity parity)

void requestToSendChanged(bool set)

void stopBitsChanged(QSerialPort::StopBits stopBits)

Reimplemented Protected Functions

virtual qint64    readData(char *data, qint64 maxSize) override

virtual qint64    readLineData(char *data, qint64 maxSize) override

virtual qint64    writeData(const char *data, qint64 maxSize) override

串口IO的主要操作有参数设置/开/关/读/写等

QSerialPort *serial = new QSerialPort;

//设置串口名

serial->setPortName(name); 

//打开串口

serial->open(QIODevice::ReadWrite); 

//设置波特率

serial->setBaudRate(BaudRate); 

//设置数据位数 

serial->setDataBits(QSerialPort::Data8); 

 //设置奇偶校验 

 serial->setParity(QSerialPort::NoParity);  

//设置停止位 

serial->setStopBits(QSerialPort::OneStop); 

//设置流控制 

serial->setFlowControl(QSerialPort::NoFlowControl);

//[1]串口设置

QSerialPort   *serialIo=new QSerialPort;

serialIo->setPortName("COM4");                    //串口名

serialIo->setBaudRate(115200);                      //波特率

serialIo->setDataBits(QSerialPort::Data8);       //数据位

serialIo->setParity(QSerialPort::NoParity);       //校验位

serialIo->setStopBits(QSerialPort::OneStop);   //停止位

serialIo->setFlowControl(QSerialPort::NoFlowControl);     //流控制一般没用

//[2]串口开启

if(serialIo->open(QIODevice::ReadWrite))

{

    qDebug()<<"串口已打开,读写模式";

}

else

{

    qDebug()<<"串口打开异常"<<serialIo->errorString();

    serialIo->clearError();

}

//[3]数据发送

const QByteArray  send_data=ui->textSend->toPlainText().toUtf8();   //一般没发字符串,特别是中文

if(serialIo->isOpen())

{

    serialIo->write(send_data);

    qDebug()<<"已发送:"<<QString::fromUtf8(send_data);

}

else

{

    qDebug()<<"发送失败,串口未打开";

}

if(!serialIo->waitForBytesWritten(30000))

{

    qDebug()<<"命令发送异常"<<serialIo->errorString();

    serialIo->clearError();

}

//[4]数据接收

connect(serialIo,&QSerialPort::readyRead,this,[this]()

{

if (serialIo->bytesAvailable())

{

//串口收到的数据可能不是连续的,需要的话应该把数据缓存下来再进行协议解析,类似tcp数据处理

        const QByteArray recv_data=serialIo->readAll();

//接收发送要一致,如果是处理字节数据,可以把QByteArray当数组一样取下标,

//或者用data()方法转为char*形式

        ui->textRecv->append(QString::fromUtf8(recv_data));      //显示

        qDebug()<<"已接收:"<<QString::fromUtf8(recv_data);

    }

});

//[5]串口关闭

serialIo->clear();

serialIo->close();

串口例程

Qt串口通信模块QSerialPort简单串口实例

mainwindows.h代码参考如下:

#ifndef    MAINWINDOW_H

#define   MAINWINDOW_H

#include <QMainWindow>

#include <QtSerialPort/QSerialPort>

#include <QtSerialPort/QSerialPortInfo>

#include <QList>

#include <QDebug>

namespace  Ui {

class MainWindow;

}

class MainWindow : public  QMainWindow

{

      Q_OBJECT

public:

 explicit  MainWindow(QWidget *parent = 0);

 ~MainWindow();

private slots:

 void on_btn_openConsole_clicked();

 void on_btn_send_clicked();

 void on_btn_clearRecv_clicked();

 void on_btn_clearSend_clicked();

 void readData();

private:

 Ui::MainWindow    *ui;

 QSerialPort            *serial;

};

#endif              // MAINWINDOW_H

mainwindows.cpp代码

#include "mainwindow.h"

#include "ui_mainwindow.h"

static const char  blankString[] = QT_TRANSLATE_NOOP("SettingsDialog", "N/A");

MainWindow::MainWindow(QWidget *parent) :

 QMainWindow(parent),

 ui(new Ui::MainWindow)

{

 ui->setupUi(this);

 serial = new QSerialPort;

    QString     description;

    QString     manufacturer;

    QString     serialNumber;

     //获取可以用的串口

    QList<QSerialPortInfo>   serialPortInfos = QSerialPortInfo::availablePorts();

    //输出当前系统可以使用的串口个数

    qDebug() << "Total numbers of ports: " << serialPortInfos.count();

     //将所有可以使用的串口设备添加到ComboBox

    for (const QSerialPortInfo &serialPortInfo : serialPortInfos)

{

         QStringList    list;

         description = serialPortInfo.description();

         manufacturer = serialPortInfo.manufacturer();

         serialNumber = serialPortInfo.serialNumber();

         list << serialPortInfo.portName()

<< (!description.isEmpty() ? description : blankString)

<< (!manufacturer.isEmpty() ? manufacturer : blankString)

<< (!serialNumber.isEmpty() ? serialNumber : blankString)

<< serialPortInfo.systemLocation()

<< (serialPortInfo.vendorIdentifier() ? QString::number(serialPortInfo.vendorIdentifier(), 16) : blankString)

              << (serialPortInfo.productIdentifier() ? QString::number(serialPortInfo.productIdentifier(), 16) : blankString);

              ui->comboBox_serialPort->addItem(list.first(), list);

     }

     ui->comboBox_serialPort->addItem(tr("custom"));

     //设置波特率

     ui->comboBox_baudRate->addItem(QStringLiteral("9600"), QSerialPort::Baud9600);

     ui->comboBox_baudRate->addItem(QStringLiteral("19200"), QSerialPort::Baud19200);

     ui->comboBox_baudRate->addItem(QStringLiteral("38400"), QSerialPort::Baud38400);

     ui->comboBox_baudRate->addItem(QStringLiteral("115200"), QSerialPort::Baud115200);

     ui->comboBox_baudRate->addItem(tr("Custom"));

     //设置数据位

ui->comboBox_dataBits->addItem(QStringLiteral("5"), QSerialPort::Data5);

    ui->comboBox_dataBits->addItem(QStringLiteral("6"), QSerialPort::Data6);

    ui->comboBox_dataBits->addItem(QStringLiteral("7"), QSerialPort::Data7);

    ui->comboBox_dataBits->addItem(QStringLiteral("8"), QSerialPort::Data8);

    ui->comboBox_dataBits->setCurrentIndex(3);

    //设置奇偶校验位

    ui->comboBox_parity->addItem(tr("None"), QSerialPort::NoParity);

    ui->comboBox_parity->addItem(tr("Even"), QSerialPort::EvenParity);

    ui->comboBox_parity->addItem(tr("Odd"), QSerialPort::OddParity);

    ui->comboBox_parity->addItem(tr("Mark"), QSerialPort::MarkParity);

    ui->comboBox_parity->addItem(tr("Space"), QSerialPort::SpaceParity);

    //设置停止位

    ui->comboBox_stopBit->addItem(QStringLiteral("1"), QSerialPort::OneStop);

    ui->comboBox_stopBit->addItem(QStringLiteral("2"), QSerialPort::TwoStop);

    //添加流控

    ui->comboBox_flowBit->addItem(tr("None"), QSerialPort::NoFlowControl);

    ui->comboBox_flowBit->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl);

    ui->comboBox_flowBit->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl);

//禁用发送按钮

   ui->btn_send->setEnabled(false);

}

MainWindow::~MainWindow()

{

       //delete serial;

      delete ui;

}

//打开串口按钮槽函数

void MainWindow::on_btn_openConsole_clicked()

{

 qDebug() << ui->btn_openConsole->text();

 if (ui->btn_openConsole->text() == tr("打开串口"))

 {

  //设置串口名字

  serial->setPortName(ui->comboBox_serialPort->currentText());

  //设置波特率

  serial->setBaudRate(ui->comboBox_baudRate->currentText().toInt());

  //设置数据位

  serial->setDataBits(QSerialPort::Data8);

  //设置奇偶校验位

  serial->setParity(QSerialPort::NoParity);

  //设置停止位

  serial->setStopBits(QSerialPort::OneStop);

  //设置流控

  serial->setFlowControl(QSerialPort::NoFlowControl);

  //打开串口

  if (serial->open(QIODevice::ReadWrite))

  {

      ui->comboBox_baudRate->setEnabled(false);

      ui->comboBox_dataBits->setEnabled(false);

      ui->comboBox_flowBit->setEnabled(false);

      ui->comboBox_parity->setEnabled(false);

      ui->comboBox_serialPort->setEnabled(false);

      ui->comboBox_stopBit->setEnabled(false);

      ui->btn_send->setEnabled(true);

      ui->btn_openConsole->setText(tr("关闭串口"));

      //信号与槽函数关联

       connect(serial, &QSerialPort::readyRead, this, &MainWindow::readData);

  }

 }

 else

 {

      //关闭串口

      //serial->clear();

      serial->close();

      //serial->deleteLater();

      //恢复设置功能

      ui->comboBox_baudRate->setEnabled(true);

      ui->comboBox_dataBits->setEnabled(true);

      ui->comboBox_flowBit->setEnabled(true);

      ui->comboBox_parity->setEnabled(true);

      ui->comboBox_serialPort->setEnabled(true);

      ui->comboBox_stopBit->setEnabled(true);

      ui->btn_openConsole->setText(tr("打开串口"));

      ui->btn_send->setEnabled(false);

   }

}

//发送数据槽函数

void MainWindow::on_btn_send_clicked()

{

      serial->write(ui->textEdit_send->toPlainText().toLatin1());

}

//清空接收数据槽函数

void MainWindow::on_btn_clearRecv_clicked()

{

      ui->textEdit_recv->clear();

}

//清空发送区槽函数

void MainWindow::on_btn_clearSend_clicked()

{

       ui->textEdit_send->clear();

}

void MainWindow::readData()

{

     QByteArray buf;

     qDebug() << "readData: " << endl;

     buf = serial->readAll();

     if (!buf.isEmpty())

     {

            QString str = ui->textEdit_recv->toPlainText();

            str += tr(buf);

            ui->textEdit_recv->clear();

            ui->textEdit_recv->append(str);

     }

}

​​​​​​​图形界面设计

图形界面相关属性设置:

用的时候在 pro 添加这句导入模块 QT += serialport

1.连接串口

第一步就是 要先获取到 可连接的所有的串口的名字

QSerialPortInfo::availablePorts()

[static] QList<QSerialPortInfo>  QSerialPortInfo::availablePorts()

Returns a list of available serial ports on the system.

返回系统上可用串行端口的列表

QSerialPortInfo

Provides information about existing serial ports.

Use the static functions to generate a list of QSerialPortInfo objects. Each QSerialPortInfo object in the list represents a single serial port and can be queried for the port name, system location, description, and manufacturer. The QSerialPortInfo class can also be used as an input parameter for the setPort() method of the QSerialPort class. See also QSerialPort.

提供关于现有串行端口的信息。

使用静态函数生成QSerialPortInfo对象列表。列表中的每个QSerialPortInfo对象表示一个串行端口,可以查询端口名称、系统位置、描述和制造商。QSerialPortInfo类还可以用作QSerialPort类的setPort()方法的输入参数。

//这样我们就获取到 可用的串口名字了

QStringList m_serialPortName;

foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())

{

         m_serialPortName << info.portName();

         qDebug()<<"serialPortName:"<<info.portName();

}

获取到串口名字列表以后,我们需要选择一个需要连接的 (自行根据选择)

2.根据串口名字 打开串口

#include<QSerialPort>

QSerialPort *m_serialPort = new QSerialPort();     //实例化串口类一个对象

if(m_serialPort->isOpen())                                    //如果串口已经打开了 先给他关闭了

{

         m_serialPort->clear();

         m_serialPort->close();

}

//设置串口名字 假设我们上面已经成功获取到了 并且使用第一个

m_serialPort->setPortName(m_serialPortName[0]);

if(!m_serialPort->open(QIODevice::ReadWrite))      //ReadWrite 的模式尝试打开串口

{

         qDebug()<<m_serialPortName[0]<<"打开失败!";

         return;

}

//打开成功

    m_serialPort->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//设置波特率和读写方向

    m_serialPort->setDataBits(QSerialPort::Data8);                           //数据位为8

    m_serialPort->setFlowControl(QSerialPort::NoFlowControl);    //无流控制

    m_serialPort->setParity(QSerialPort::NoParity);                          //无校验位

    m_serialPort->setStopBits(QSerialPort::OneStop);                    //一位停止位

    //连接信号槽 当下位机发送数据QSerialPortInfo 会发送个 readyRead 信号,我们定义个槽void receiveInfo()解析数据

connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo()));

3.下位机(单片机) ,上位机(Qt程序) 发送交互数据

//接收单片机的数据

void receiveInfo()

{

                  QByteArray info = m_serialPort->readAll();

                  QByteArray hexData = info.toHex();

                  //这里面的协议 你们自己定义就行  单片机发什么 代表什么 我们这里简单模拟一下

                  if(hexData == "0x10000")

                  {

                          //do something

                  }

                  else if(hexData  == "0x100001")        

                  {

                          //do something

                  }

}

//向单片机发送数据

//基本和单片机交互 数据 都是16进制的 我们这里自己写一个 Qstring 转为 16进制的函数    

void convertStringToHex(const QString &str, QByteArray &byteData)

{

            int hexdata,lowhexdata;

             int hexdatalen = 0;

             int len = str.length();

             byteData.resize(len/2);

             char lstr,hstr;

             for(int i=0; i<len; )

             {

                 //char lstr,

                 hstr=str[i].toLatin1();

                 if(hstr == ' ')

                 {

                     i++;

                     continue;

                 }

                 i++;

                 if(i >= len)

                     break;

                 lstr = str[i].toLatin1();

                 hexdata = convertCharToHex(hstr);

                 lowhexdata = convertCharToHex(lstr);

                 if((hexdata == 16) || (lowhexdata == 16))

                     break;

                 else

                     hexdata = hexdata*16+lowhexdata;

                 i++;

                 byteData[hexdatalen] = (char)hexdata;

                 hexdatalen++;

             }

             byteData.resize(hexdatalen);

}

//另一个 函数 char 转为 16进制

char SerialPort::convertCharToHex(char ch)

{

             /*0x30等于十进制的4848也是0ASCII值,1-9ASCII值是49-57,,所以某一个值-0x30,就是将字符0-9转换为0-9*/

             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 (-1);

}

//写两个函数 向单片机发送数据

void sendInfo(char* info,int len){

                  for(int i=0; i<len; ++i)

{

                 printf("0x%x\n", info[i]);

}

             m_serialPort->write(info,len);//这句是真正的给单片机发数据 用到的是QIODevice::write 具体可以看文档

         }

         void sendInfo(const QString &info){

                  QByteArray sendBuf;

             if (info.contains(" "))

             {

                 info.replace(QString(" "),QString(""));  //我这里是把空格去掉,根据你们定的协议来

             }

             qDebug()<<"Write to serial: "<<info;

             convertStringToHex(info, sendBuf);         //QString 转换 hex

             m_serialPort->write(sendBuf);//这句是真正的给单片机发数据 用到的是QIODevice::write 具体可以看文档

         }

4.析构的时候 关闭串口

if (m_serialPort->isOpen())

{

        m_serialPort->close();

}

delete m_serialPort;

源码:

widget.h

#ifndef    WIDGET_H

#define    WIDGET_H

#include <QWidget>

#include <QSerialPort>

#include <QSerialPortInfo>

#include <QComboBox>

#include <QPushButton>

namespace Ui {

class Widget;

}

class Widget : public QWidget

{

    Q_OBJECT

public:

    explicit Widget(QWidget *parent = 0);

    ~Widget();

    void initUI();

    QStringList getPortNameList();    //获取所有可用的串口列表

    void openPort();//打开串口

public slots:

    void receiveInfo();

private:

    Ui::Widget *ui;

    QSerialPort* m_serialPort;     //串口类

    QStringList m_portNameList;

    QComboBox* m_PortNameComboBox;

    QPushButton* m_OpenPortButton;

};

#endif            // WIDGET_H

widget.cpp

#include "widget.h"

#include "ui_widget.h"

#include <QLayout>

#include <QDebug>

Widget::Widget(QWidget *parent) :

    QWidget(parent),

    ui(new Ui::Widget)

{

    ui->setupUi(this);

    m_serialPort = new QSerialPort();

    initUI();

    m_portNameList = getPortNameList();

    m_PortNameComboBox->addItems(m_portNameList);

    connect(m_OpenPortButton,&QPushButton::clicked,this,&Widget::openPort);

}

Widget::~Widget()

{

    if (m_serialPort->isOpen())

    {

        m_serialPort->close();

    }

    delete m_serialPort;

    delete ui;

}

void Widget::initUI()

{

    this->setWindowTitle("码农小明 test QSerialPort");

    m_OpenPortButton = new QPushButton();

    m_OpenPortButton->setText("打开串口");

    m_PortNameComboBox  = new QComboBox();

    QHBoxLayout *m_layout = new QHBoxLayout();

    m_layout->addWidget(m_PortNameComboBox);

    m_layout->addWidget(m_OpenPortButton);

    this->setLayout(m_layout);

}

QStringList Widget::getPortNameList()

{

    QStringList m_serialPortName;

    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())

    {

        m_serialPortName << info.portName();

        qDebug()<<"serialPortName:"<<info.portName();

    }

    return m_serialPortName;

}

void Widget::openPort()

{

    if(m_serialPort->isOpen())     //如果串口已经打开了 先给他关闭了

    {

        m_serialPort->clear();

        m_serialPort->close();

    }

    m_serialPort->setPortName(m_PortNameComboBox->currentText());//当前选择的串口名字

    if(!m_serialPort->open(QIODevice::ReadWrite))        //ReadWrite 的模式尝试打开串口

    {

        qDebug()<<"打开失败!";

        return;

    }

    qDebug()<<"串口打开成功!";

    m_serialPort->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//设置波特率和读写方向

    m_serialPort->setDataBits(QSerialPort::Data8);      //数据位为8

    m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制

    m_serialPort->setParity(QSerialPort::NoParity);         //无校验位

    m_serialPort->setStopBits(QSerialPort::OneStop);     //一位停止位

    connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo()));

}

//接收到单片机发送的数据进行解析

void Widget::receiveInfo()

{

    QByteArray info = m_serialPort->readAll();

    qDebug()<<"receive info:"<<info;

}

QT实现串口通信

要实现串口通信,需要知道串口通信需要的信息

主要参数有:波特率、校验位、数据位、停止位、控制流

主要操作有:串口的打开和关闭、刷新设备串口、接发数据、开关显示灯等。

实现效果如图:

界面设计如下:

每个控件类名如下:

LED灯是QLable控件,设置它的长宽都是24px,然后鼠标右击,选择“样式表”,在样式表中添加代码。

最后附赠完整源码。

第一步:在头文件中引入 QtSerialPort 类的两个头文件

// 引入串口通信的两个头文件(第一步)

#include <QtSerialPort/QSerialPort>           // 提供访问串口的功能

#include <QtSerialPort/QSerialPortInfo>     // 提供系统中存在的串口信息

第二步:在工程文件中添加以下代码

# 引入串口工程类型

QT       += serialport

第三步:在头文件中定义全局的串口对象

QSerialPort     *serial;                                    // 定义全局的串口对象(第三步)

第四步:参数设置,在头文件中定义初始化参数的函数和参数变量名,在.cpp文件中实现函数

public:

void        SerialPortInit();                               // 串口初始化(参数配置)

private:

// 参数配置

    QStringList     baudList;                           //波特率

    QStringList     parityList;                          //校验位

    QStringList     dataBitsList;                       //数据位

    QStringList     stopBitsList;                       //停止位

    QStringList     flowControlList;                 //控制流

// 串口初始化(参数配置)

void MainWindow::SerialPortInit()

{

    serial = new QSerialPort;                       //申请内存,并设置父对象

    // 获取计算机中有效的端口号,然后将端口号的名称给端口选择控件

    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())

    {

        serial->setPort(info);                                   // 在对象中设置串口

        if(serial->open(QIODevice::ReadWrite))      // 以读写方式打开串口

        {

            ui->PortBox->addItem(info.portName());  // 添加计算机中的端口

            serial->close();                                           // 关闭

        } else

        {

            qDebug() << "串口打开失败,请重试";

        }

    }

    // 参数配置

    // 波特率,波特率默认选择57600 ,禁止用户点击

    ui->BaudBox->addItem("57600");

    serial->setBaudRate(QSerialPort::Baud57600);

    ui->BaudBox->setDisabled(true);

    // 校验,校验默认选择无

    ui->ParityBox->addItem("无");

    serial->setParity(QSerialPort::NoParity);

    // 数据位,数据位默认选择8

    ui->BitBox->addItem("8");

    serial->setDataBits(QSerialPort::Data8);

    // 停止位,停止位默认选择1

    ui->StopBox->addItem("1");

    serial->setStopBits(QSerialPort::OneStop);

    // 控制流,默认选择无

    ui->ControlBox->addItem("无");

    serial->setFlowControl(QSerialPort::NoFlowControl);

    // 刷新串口

    RefreshSerialPort(0);

    // 信号

connect(serial,&QSerialPort::readyRead,this,&MainWindow::DataReceived);      //接收数据

connect(ui->SendWordOrder,&QPushButton::clicked,this,&MainWindow::DataSend); //发送数据

connect(ui->SendButton,&QPushButton::clicked,this,&MainWindow::DataSend);        //发送数据

connect(ui->SendEditBtn1,&QPushButton::clicked,this,&MainWindow::DataSend);     //发送数据

connect(ui->SendEditBtn2,&QPushButton::clicked,this,&MainWindow::DataSend); //发送数据

connect(ui->SendEditBtn3,&QPushButton::clicked,this,&MainWindow::DataSend); //发送数据

}

第五步:刷新串口,及时更新可用的串口

// 刷新串口

void MainWindow::RefreshSerialPort(int index)

{

    QStringList portNameList;                                                      // 存储所有串口名

    if(index != 0)

    {

        serial->setPortName(ui->PortBox->currentText());             //设置串口号

    }

    else

    {

        ui->PortBox->clear();                                               //关闭串口号

        ui->PortBox->addItem("刷新");                                //添加刷新

        foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //添加新串口

        {

            portNameList.append(info.portName());

        }

        ui->PortBox->addItems(portNameList);

        ui->PortBox->setCurrentIndex(1);                             // 当前串口号为COM1

        serial->setPortName(ui->PortBox->currentText());   //设置串口号

   }

}

第六步:发送数据和接收数据

// 接收数据,使用read () / readLine () / readAll ()

void MainWindow::DataReceived()

{

    char BUF[512] = {0};                                       // 存储转换类型后的数据

    QByteArray data = serial->readAll();             // 读取数据

    if(!data.isEmpty())                                           // 接收到数据

    {

        QString str = ui->DataReceived->toPlainText();         // 返回纯文本

        str += tr(data);                                            // 数据是一行一行传送的,要保存所有数据

        ui->DataReceived->clear();                        // 清空之前的数据

        ui->DataReceived->append(str);               // 将数据放入控件中

        qDebug() << "str info: " << ui->DataReceived->toPlainText();

         // 清除之前的数据,防止追加,因为每次获取的数据不一样

        int index = str.indexOf("\r\n");                // 找到,返回索引值,找不到,返回-1

        if(index != -1)

        {

            snprintf(BUF,500,"%s", str.left(index + 2).toUtf8().data());        // QString转为char * 类型

            qDebug() << "BUF info: " << BUF;                                        // 数据类型转换成功

            str.remove(0,index + 2);

            // 处理获取到的数据,将其放入对应的控件中          

        }

    }

}

// 发送数据,write ()

void MainWindow::DataSend()

{

    serial->write(ui->DataSend->toPlainText().toLatin1());      // 串口发送数据

}

第七步:打开串口和关闭串口,当打开串口后,显示绿灯;关闭串口后,显示红灯

// 串口开关

void MainWindow::on_OpenSerialButton_clicked()

{

    if(serial->isOpen())                                  // 如果串口打开了,先给他关闭

    {

        serial->clear();

        serial->close();

        // 关闭状态,按钮显示打开串口

        ui->OpenSerialButton->setText("打开串口");

        // 关闭状态,允许用户操作

        ui->BaudBox->setDisabled(false);

        ui->ParityBox->setDisabled(false);

        ui->BitBox->setDisabled(false);

        ui->StopBox->setDisabled(false);

        ui->ControlBox->setDisabled(false);

        // 禁止操作发送字符操作

        ui->SendWordOrder->setDisabled(true);

        ui->SendButton->setDisabled(true);

        // 关闭状态,颜色为绿色

        ui->OpenSerialButton->setStyleSheet("color: green;");

        // 关闭,显示灯为红色

        LED(true);

        // 清空数据

        ui->DataReceived->clear();

        ui->DataSend->clear();

    }

    else            // 如果串口关闭了,先给他打开

    {

        //当前选择的串口名字

        serial->setPortName(ui->PortBox->currentText());

        //用ReadWrite 的模式尝试打开串口,无法收发数据时,发出警告

        if(!serial->open(QIODevice::ReadWrite))

        {

            QMessageBox::warning(this,tr("提示"),tr("串口打开失败!"),QMessageBox::Ok);

            return;

         }

        // 打开状态,按钮显示“关闭串口”

        ui->OpenSerialButton->setText("关闭串口");

        // 打开状态,禁止用户操作

        ui->BaudBox->setDisabled(true);

        ui->ParityBox->setDisabled(true);

        ui->BitBox->setDisabled(true);

        ui->StopBox->setDisabled(true);

        ui->ControlBox->setDisabled(true);

        // 允许操作“发送字符操作”

        ui->SendWordOrder->setDisabled(false);

        ui->SendButton->setDisabled(false);

        // 打开状态,颜色为红色

        ui->OpenSerialButton->setStyleSheet("color: red;");

        // 打开,显示灯为绿色

        LED(false);

    }

}

// 开关显示灯

void  MainWindow::LED(bool changeColor)

{

    if(changeColor == false)

    {

        // 显示绿色

        ui->LED->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 229, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;");

    }

    else

    {

        // 显示红色

        ui->LED->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(255, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;");

    }

}

第八步:相关槽函数

// 控件中添加 指令“###”

void MainWindow::on_SendButton_clicked()

{

    on_ClearButton_clicked();

    ui->DataSend->append("###");

}

// 清空控件

void MainWindow::on_ClearButton_clicked()

{

    ui->DataSend->setText("");

}

// 清空接收到的数据

void MainWindow::on_ClearShowButton_clicked()

{

    ui->DataReceived->setText("");

}

// 点击发送后,获取串口信息并展示在接受控件中

void MainWindow::on_SendEditBtn1_clicked()

{

    on_ClearButton_clicked();

    QString EditText = ui->Edit1->text();               //获取发送框内容

    ui->DataSend->setText(EditText);                     //将文本内容放在发送栏中

}

void MainWindow::on_SendEditBtn2_clicked()

{

    on_ClearButton_clicked();

    QString EditText = ui->Edit2->text();               //获取发送框内容

    // qDebug() << "Edit1 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中

}

void MainWindow::on_SendEditBtn3_clicked()

{

    on_ClearButton_clicked();

    QString EditText = ui->Edit3->text();               //获取发送框内容

    // qDebug() << "Edit1 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中

}

void MainWindow::on_SendWordOrder_clicked()

{

    on_SendButton_clicked();

}

      1. 源码:

工程文件.pro文件源码:

QT       += core gui

# 引入串口工程类型

QT       += serialport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use

# any Qt feature that has been marked deprecated (the exact warnings

# depend on your compiler). Please consult the documentation of the

# deprecated API in order to know how to port your code away from it.

DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.

# In order to do so, uncomment the following line.

# You can also select to disable deprecated APIs only up to a certain version of Qt.

#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \

    main.cpp \

    mainwindow.cpp

HEADERS += \

    mainwindow.h

FORMS += \

    mainwindow.ui

# Default rules for deployment.

qnx: target.path = /tmp/$${TARGET}/bin

else: unix:!android: target.path = /opt/$${TARGET}/bin

!isEmpty(target.path): INSTALLS += target

头文件源码:

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include <QMainWindow>

// 引入串口通信的两个头文件(第一步)

#include <QtSerialPort/QSerialPort>           // 提供访问串口的功能

#include <QtSerialPort/QSerialPortInfo>     // 提供系统中存在的串口信息

QT_BEGIN_NAMESPACE

namespace Ui { class MainWindow; }

QT_END_NAMESPACE

class MainWindow : public QMainWindow

{

    Q_OBJECT

public:

    MainWindow(QWidget *parent = nullptr);

    ~MainWindow();

    // 串口功能

    void        SerialPortInit();                           // 串口初始化(参数配置)

    void        RefreshSerialPort(int index);      // 刷新串口

public slots:

    // 串口槽函数

    void        DataReceived();                        // 接收数据

private slots:

    // 串口槽函数

    void        DataSend();                                    // 发送数据

    void        on_OpenSerialButton_clicked();      // 串口开关

    void        on_SendButton_clicked();               // 控件中添加 #

    void        on_ClearButton_clicked();              // 清空控件中的所有 #

    void        on_ClearShowButton_clicked();     // 清空接收到的数据

    void        LED(bool changeColor);               // 开关显示灯

    // 点击发送,接收数据

    void        on_SendEditBtn1_clicked();

    void        on_SendEditBtn2_clicked();

    void        on_SendEditBtn3_clicked();

    void       on_SendWordOrder_clicked();

private:

    Ui::MainWindow   *ui;

    // 串口变量

    QSerialPort           *serial;                        // 定义全局的串口对象(第三步)

    // 参数配置

    QStringList     baudList;                          //波特率

    QStringList     parityList;                         //校验位

    QStringList     dataBitsList;                     //数据位

    QStringList     stopBitsList;                     //停止位

    QStringList     flowControlList;               //控制流

};

#endif             // MAINWINDOW_H

.cpp文件源码:

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include <QDebug>

#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)

    : QMainWindow(parent)

    , ui(new Ui::MainWindow)

{

    ui->setupUi(this);

    SerialPortInit();

}

// 串口初始化(参数配置)

void MainWindow::SerialPortInit()

{

    serial = new QSerialPort;                       //申请内存,并设置父对象

    // 获取计算机中有效的端口号,然后将端口号的名称给端口选择控件

    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())

    {

        serial->setPort(info);                                   // 在对象中设置串口

        if(serial->open(QIODevice::ReadWrite))      // 以读写方式打开串口

        {

            ui->PortBox->addItem(info.portName());      // 添加计算机中的端口

            serial->close();                                               // 关闭

        } else

        {

            qDebug() << "串口打开失败,请重试";

        }

    }

    // 参数配置

    // 波特率,波特率默认选择57600 ,禁止用户点击

    ui->BaudBox->addItem("57600");

    serial->setBaudRate(QSerialPort::Baud57600);

    ui->BaudBox->setDisabled(true);

    // 校验,校验默认选择无

    ui->ParityBox->addItem("无");

    serial->setParity(QSerialPort::NoParity);

    // 数据位,数据位默认选择8

    ui->BitBox->addItem("8");

    serial->setDataBits(QSerialPort::Data8);

    // 停止位,停止位默认选择1

    ui->StopBox->addItem("1");

    serial->setStopBits(QSerialPort::OneStop);

    // 控制流,默认选择无

    ui->ControlBox->addItem("无");

    serial->setFlowControl(QSerialPort::NoFlowControl);

    // 刷新串口

    RefreshSerialPort(0);

    // 信号

    connect(serial,&QSerialPort::readyRead,this,&MainWindow::DataReceived);                    // 接收数据

    connect(ui->SendWordOrder,&QPushButton::clicked,this,&MainWindow::DataSend);    // 发送数据

    connect(ui->SendButton,&QPushButton::clicked,this,&MainWindow::DataSend);           // 发送数据

    connect(ui->SendEditBtn1,&QPushButton::clicked,this,&MainWindow::DataSend);        // 发送数据

    connect(ui->SendEditBtn2,&QPushButton::clicked,this,&MainWindow::DataSend);        // 发送数据

    connect(ui->SendEditBtn3,&QPushButton::clicked,this,&MainWindow::DataSend);       // 发送数据

}

// 刷新串口

void MainWindow::RefreshSerialPort(int index)

{

    QStringList     portNameList;                                        // 存储所有串口名

    if(index != 0)

    {

        serial->setPortName(ui->PortBox->currentText());             //设置串口号

    }

    else

    {

        ui->PortBox->clear();                                               //关闭串口号

        ui->PortBox->addItem("刷新");                                //添加刷新

        foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //添加新串口

        {

            portNameList.append(info.portName());

        }

        ui->PortBox->addItems(portNameList);

        ui->PortBox->setCurrentIndex(1);                                       // 当前串口号为COM1

        serial->setPortName(ui->PortBox->currentText());             //设置串口号

   }

}

// 接收数据,使用read () / readLine () / readAll ()

void MainWindow::DataReceived()

{

    char BUF[512] = {0};                                       // 存储转换类型后的数据

    QByteArray data = serial->readAll();              // 读取数据

    if(!data.isEmpty())                                           // 接收到数据

    {

        QString str = ui->DataReceived->toPlainText();     // 返回纯文本

        str += tr(data);                                                        // 数据是一行一行传送的,要保存所有数据

        ui->DataReceived->clear();                                   // 清空之前的数据

        ui->DataReceived->append(str);                          // 将数据放入控件中

        qDebug() << "str info: " << ui->DataReceived->toPlainText();

         // 清除之前的数据,防止追加,因为每次获取的数据不一样

        int index = str.indexOf("\r\n");                               // 找到,返回索引值,找不到,返回-1

        if(index != -1)

        {

            snprintf(BUF,500,"%s", str.left(index + 2).toUtf8().data());      // QString转为char * 类型

            qDebug() << "BUF info: " << BUF;

            str.remove(0,index + 2);

            // 处理获取到的数据,将其放入对应的控件中

        }

    }

}

// 发送数据,write ()

void MainWindow::DataSend()

{

    serial->write(ui->DataSend->toPlainText().toLatin1());      // 串口发送数据

}

// 开关显示灯

void  MainWindow::LED(bool changeColor)

{

    if(changeColor == false)

    {

        // 显示绿色

        ui->LED->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 229, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;");

    }

    else

    {

        // 显示红色

        ui->LED->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(255, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;");

    }

}

MainWindow::~MainWindow()

{

    delete ui;

}

// 串口开关

void MainWindow::on_OpenSerialButton_clicked()

{

    if(serial->isOpen())                                        // 如果串口打开了,先给他关闭

    {

        serial->clear();

        serial->close();

        // 关闭状态,按钮显示打开串口

        ui->OpenSerialButton->setText("打开串口");

        // 关闭状态,允许用户操作

        ui->BaudBox->setDisabled(false);

        ui->ParityBox->setDisabled(false);

        ui->BitBox->setDisabled(false);

        ui->StopBox->setDisabled(false);

        ui->ControlBox->setDisabled(false);

        // 禁止操作发送字符操作

        ui->SendWordOrder->setDisabled(true);

        ui->SendButton->setDisabled(true);

        // 关闭状态,颜色为绿色

        ui->OpenSerialButton->setStyleSheet("color: green;");

        // 关闭,显示灯为红色

        LED(true);

        // 清空数据

        ui->DataReceived->clear();

        ui->DataSend->clear();

    }

    else                                                        // 如果串口关闭了,先给他打开

    {

        //当前选择的串口名字

        serial->setPortName(ui->PortBox->currentText());

        //ReadWrite 的模式尝试打开串口,无法收发数据时,发出警告

        if(!serial->open(QIODevice::ReadWrite))

        {

            QMessageBox::warning(this,tr("提示"),tr("串口打开失败!"),QMessageBox::Ok);

            return;

         }

        // 打开状态,按钮显示关闭串口

        ui->OpenSerialButton->setText("关闭串口");

        // 打开状态,禁止用户操作

        ui->BaudBox->setDisabled(true);

        ui->ParityBox->setDisabled(true);

        ui->BitBox->setDisabled(true);

        ui->StopBox->setDisabled(true);

        ui->ControlBox->setDisabled(true);

        // 允许操作发送字符操作

        ui->SendWordOrder->setDisabled(false);

        ui->SendButton->setDisabled(false);

        // 打开状态,颜色为红色

        ui->OpenSerialButton->setStyleSheet("color: red;");

        // 打开,显示灯为绿色

        LED(false);

    }

}

// 控件中添加 #

void MainWindow::on_SendButton_clicked()

{

    on_ClearButton_clicked();

    ui->DataSend->append("###");

}

// 清空控件

void MainWindow::on_ClearButton_clicked()

{

    ui->DataSend->setText("");

}

// 清空接收到的数据

void MainWindow::on_ClearShowButton_clicked()

{

    ui->DataReceived->setText("");

}

// 点击发送后,获取串口信息并展示在接受控件中

void MainWindow::on_SendEditBtn1_clicked()

{

    on_ClearButton_clicked();

    QString EditText = ui->Edit1->text();                //获取发送框内容

    ui->DataSend->setText(EditText);                     //将文本内容放在发送栏中

}

void MainWindow::on_SendEditBtn2_clicked()

{

    on_ClearButton_clicked();

    QString EditText = ui->Edit2->text();                 //获取发送框内容

    // qDebug() << "Edit1 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中

}

void MainWindow::on_SendEditBtn3_clicked()

{

    on_ClearButton_clicked();

    QString EditText = ui->Edit3->text();                 //获取发送框内容

    // qDebug() << "Edit1 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中

}

void MainWindow::on_SendWordOrder_clicked()

{

    on_SendButton_clicked();

}

运行后效果:

http://www.dtcms.com/a/272281.html

相关文章:

  • C语言——预处理详解
  • C#中异步任务取消:CancellationToken
  • 【C++详解】STL-list模拟实现(深度剖析list迭代器,类模板未实例化取嵌套类型问题)
  • 【TCP/IP】10. 引导协议与动态主机配置协议
  • prometheus+grafana接入nginx实战
  • 零成本实现商品图换背景
  • 静态路由实验(2)
  • Vue3 深度解析:渲染器与渲染函数的奥秘
  • 【PTA数据结构 | C语言版】链式栈的3个操作
  • linux 4.14 kernel屏蔽arm arch timer的方法
  • 网络编程与自动化
  • 高亚科技签约奕源金属,助力打造高效智能化采购管理体系
  • Flask 入门教程:用 Python 快速搭建你的第一个 Web 应用
  • 在 Ubuntu 上安装和配置 Kafka
  • 下一代防火墙-终端安全防护
  • 普林斯顿大学DPPO机器人学习突破:Diffusion Policy Policy Optimization 全新优化扩散策略
  • Eigen 几何模块深拆:Isometry3d vs Affine3d + 变换矩阵本质详解
  • OSPF协议:核心概念与配置要点解析
  • 虚拟项目[3D物体测量]
  • 从真人到数字分身:3D人脸扫描设备在高校数字人建模教学中的应用
  • 强化学习 MDP
  • Selenium 4 教程:自动化 WebDriver 管理与 Cookie 提取 || 用于解决chromedriver版本不匹配问题
  • 《PyQt6-3D:开启Python 3D开发新世界》
  • Windows Edge 播放 H.265 视频指南
  • OpenAI正准备推出一款搭载人工智能功能的网络浏览器,试图直接挑战Alphabet旗下
  • 前端面试专栏-算法篇:21. 链表、栈、队列的实现与应用
  • NAT技术(网络地址转换)
  • 【实战】使用 ELK 搭建 Spring Boot Docker 容器日志监控系统
  • OSPF实验以及核心原理全解
  • 【SkyWalking】配置告警规则并通过 Webhook 推送钉钉通知