当前位置:网站首页>QT widget's simple serial port assistant (qserialport)

QT widget's simple serial port assistant (qserialport)

2022-06-11 02:02:00 Penguins on the volcano


GitHub Address :     QWidgetPro , Select subproject QSerialAssistant .pro( At present, there is only one )

QT For other articles, please click here :     QT QUICK QML Learning notes


One 、 demonstration

Qt As host computer , Connecting to the hardware , Serial port is the most commonly used function . This article has written a simple serial port program which is easy to start , The demonstration is as follows :

 Insert picture description here

Two 、 front end UI

Add a new Qt Widgets engineering
 Insert picture description here

1. UI Layout

The layout is generated by dragging and dropping in the design :
 Insert picture description here

2. Control rename

Modify the control name as follows :
 Insert picture description here

3. Create slot function

Create a slot function for the following control , Click on UI Automatically generated

private slots:
    void on_pushButton_operate_clicked();
    void on_pushButton_send_clicked();
    void on_pushButton_clearRcv_clicked();
    void on_pushButton_clearSend_clicked();

Other options such as options in the drop-down box 、 The default values are set in the program .

3、 ... and 、 Back end implementation ideas

1. add to QSerialPort modular

stay .pro Add to file QT += serialport

And then in mainwindow.h Add :

#include <QSerialPort> // Provides the function of accessing the serial port 
#include <QSerialPortInfo> // Provide the information of the serial port in the system 

Be careful , stay Qt4 There is a third-party module QextSerialPort, here we are Qt5.1 The official provided QSerialPort modular .

2. Initialize settings

Instantiate objects 、 Establish signal slot 、 Initialize the contents of the control

void MainWindow::initConfig() {
    

    // Create objects , And establish signal slot 
    serial = new QSerialPort(this);
    // Read the signal slot of the function , See the following for details 
    QObject::connect(serial, &QSerialPort::readyRead, this, &MainWindow::serial_readyRead);
    // Click event after upgrading the port number drop-down box , See you later 
    QObject::connect(ui->comboBox_port, SIGNAL(clicked()), this, SLOT(updataPortNum()));

    // Add port number 
    updataPortNum();
    ui->comboBox_port->setCurrentIndex(0);

    // Add baud rate 
    QStringList baudList;
    baudList << "115200" << "57600" << "9600" ;
    ui->comboBox_baud->addItems(baudList);
    ui->comboBox_baud->setCurrentText("115200");

    // Add stop bit 、 Add data bits 、 Add check digit 
    ...
	// Set default text 
    ...
}

3. Serial port settings

At Click “OPEN” Is triggered when , Mainly to check whether the serial port is open 、 Is it occupied 、 Serial port configuration 、 Set the serial port status , Open the serial port , The core code is as follows :

void MainWindow::on_pushButton_operate_clicked()
{
    
    if (ui->pushButton_operate->text() == QString("OPEN")) {
    
    	// Check whether the serial port is occupied 
        const QString portnameStr = ui->comboBox_port->currentText();
        QSerialPortInfo info(portnameStr);
        if(info.isBusy()){
    
            qDebug()<< "The serial port is occupied" <<portnameStr;
            return;
        }
		...
		/// Serial port configuration 
        // Empty buffer 
        serial->flush();
        // Set the port number 
        serial->setPortName(portnameStr);
        // set baud rate 
        serial->setBaudRate( static_cast<QSerialPort::BaudRate> (ui->comboBox_baud->currentText().toInt()) );
        // Set stop bit 、 set data bit 、 Setup verification 、 Set up flow control 
		...
		
        isSerialOpen = serial->open(QIODevice::ReadWrite);
        ...
    }
}

4. Data sending

Click Send button , send data

void MainWindow::on_pushButton_send_clicked()
{
    
	// Simple text box with  toPlainText()  Take the content of the text box  toUtf8  Is converted to utf8 Byte stream in format 
    QByteArray data = ui->textEdit_send->toPlainText().toUtf8();
    serial->write(data);
}

5. Data reception

The signal slot has been established during initialization :

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

The serial port is set , And open the serial port , Every time the serial port receives data, it will send this QSerialPort::readyRead The signal . We need to define a in our program slot, And compare it with this signal Connect . such , Every time new data comes , We can do that slot Read data in . At this time, be sure to read all the data in the serial port buffer , You can use readAll() To achieve , as follows :

void MainWindow::serial_readyRead()
{
    
    // Read the previously received data from the interface 
    QString recv = ui->textEdit_rcv->toPlainText();
    // Read data from receive buffer 
    QByteArray buffer = serial->readAll();
    // Add the data just read to the data read in the interface 
    recv += QString(buffer);
    // Clear the display 
    ui->textEdit_rcv->clear();
    // Update display 
    ui->textEdit_rcv->append(recv);
}

6. Automatically obtain the serial port on the hardware

● Get the serial number of the core program

    // Clear serial port number 
    ui->comboBox_port->clear();
    // Traverse  QSerialPortInfo,  Add to the serial port drop-down box 
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){
    
        ui->comboBox_port->addItem(info.portName());
    }

Every time I click the serial port number drop-down box , That's the following , The serial port number can be updated in real time .
 Insert picture description here
But QComboBox Control has no click event , Abominable !

So I found this article ,QT in ui Interface controls QComboBox Implement mouse click events

● promote QComboBox

You can click on the details , The core idea is as follows :

Customize a class MyComboBox Inherit QComboBox class . stay MyComboBox Class mousePressEvent Mouse click event

void MyComboBox::mousePressEvent(QMouseEvent *event)
{
    
    if(event->button() == Qt::LeftButton){
    
        emit clicked();     // Trigger clicked The signal 
    }
    // Pass the event to the parent class for processing , This sentence is very important , without , The parent class cannot handle the original click event 
    QComboBox::mousePressEvent(event);
}

And then in ui The interface will ComboBox Promote to self created MyComboBox. The specific operation is :

open ui Interface ----->> Choose QComboBox Control , Right click ----->> choice “ Upgrade to ”----->> stay “ In the promoted class name ” Fill in the new class “MyComboBox” name ----->> Click on “ add to ” Button ----->> Click again “ promote ” Button . Please refer to the link article above for details .

● Establish signal slot

// Connect the signal slot , Already initialized 
QObject::connect(ui->comboBox_port, SIGNAL(clicked()), this, SLOT(updataPortNum()));

// In slot function , Update serial port number 
void MainWindow:: updataPortNum(void) {
    

    // Clear serial port number 
    ui->comboBox_port->clear();

    // Traverse  QSerialPortInfo,  Add to the serial port drop-down box 
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){
    
        ui->comboBox_port->addItem(info.portName());
    }
}

Four 、 Part of the code

mainwindow.cpp in :

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , isSerialOpen(false)
{
    
    ui->setupUi(this);

    // Initialize configuration 
    initConfig();
}

MainWindow::~MainWindow()
{
    
    delete ui;
}

void MainWindow::initConfig() {
    

    // Create objects , And establish signal slot 
    serial = new QSerialPort(this);
    // Read the signal slot of the function ,  See blog for details 
    QObject::connect(serial, &QSerialPort::readyRead, this, &MainWindow::serial_readyRead);
    // Click event after upgrading the port number drop-down box 
    QObject::connect(ui->comboBox_port, SIGNAL(clicked()), this, SLOT(updataPortNum()));

    // Add port number 
    updataPortNum();
    ui->comboBox_port->setCurrentIndex(0);

    // Add baud rate 
    QStringList baudList;
    baudList << "115200" << "57600" << "9600" ;
    ui->comboBox_baud->addItems(baudList);
    ui->comboBox_baud->setCurrentText("115200");

    // Add stop bit 
    QStringList stopBitsList;
    stopBitsList << "1" << "1.5" << "2";
    ui->comboBox_stop->addItems(stopBitsList);
    ui->comboBox_stop->setCurrentText("1");

    // Add data bits 
    QStringList dataBitsList;
    dataBitsList << "8" << "7" << "6";
    ui->comboBox_data->addItems(dataBitsList);
    ui->comboBox_data->setCurrentText("8");

    // Add check digit 
    QStringList checkList;
    checkList << "NO" << "EVEN"<< "ODD" ;
    ui->comboBox_check->addItems(checkList);
    ui->comboBox_check->setCurrentText("NO");

    ui->pushButton_operate->setText("OPEN");
    ui->textEdit_send->setText("123456789\r\n");
}

//-- Slot function , Click the port drop-down box to update 
void MainWindow:: updataPortNum(void) {
    

    // Clear serial port number 
    ui->comboBox_port->clear();

    // Traverse  QSerialPortInfo,  Add to the serial port drop-down box 
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){
    
        ui->comboBox_port->addItem(info.portName());
    }
}

// Slot function : Read serial port data and update 
void MainWindow::serial_readyRead()
{
    
    // Read the previously received data from the interface 
    QString recv = ui->textEdit_rcv->toPlainText();

    // Read data from receive buffer 
    QByteArray buffer = serial->readAll();

    // Add the data just read to the data read in the interface 
    recv += QString(buffer);

    // Clear the display 
    ui->textEdit_rcv->clear();

    // Update display 
    ui->textEdit_rcv->append(recv);
}


void MainWindow::configSetEnable(bool b)
{
    
    ui->comboBox_port->setEnabled(b);
    ui->comboBox_baud->setEnabled(b);
    ui->comboBox_stop->setEnabled(b);
    ui->comboBox_data->setEnabled(b);
    ui->comboBox_check->setEnabled(b);

    //
    ui->pushButton_send->setEnabled(!b);
}

void MainWindow::on_pushButton_operate_clicked()
{
    
    if (ui->pushButton_operate->text() == QString("OPEN")) {
    

        const QString portnameStr = ui->comboBox_port->currentText();

        QSerialPortInfo info(portnameStr);
        if(info.isBusy()){
    
            qDebug()<< "The serial port is occupied" <<portnameStr;
            return;
        }

        ui->pushButton_operate->setText("CLOSE");
        // Empty buffer 
        serial->flush();
        // Set the port number 
        serial->setPortName(portnameStr);
        // set baud rate 
        serial->setBaudRate( static_cast<QSerialPort::BaudRate> (ui->comboBox_baud->currentText().toInt()) );
        // Set stop bit 
        serial->setStopBits( static_cast<QSerialPort::StopBits> (ui->comboBox_stop->currentText().toInt()));
        // set data bit 
        serial->setDataBits( static_cast<QSerialPort::DataBits> (ui->comboBox_data->currentText().toInt()) );
        // Setup verification 
        serial->setParity  ( static_cast<QSerialPort::Parity>   (ui->comboBox_check->currentIndex()));
        // Set up flow control 
        serial->setFlowControl(QSerialPort::NoFlowControl);

        isSerialOpen = serial->open(QIODevice::ReadWrite);
        if (!isSerialOpen) {
    
            qDebug()<< QString("Failed to open serial port:") << portnameStr << serial->errorString();
            serial->clearError();
            configSetEnable(true);
        }
        else {
    
            qDebug()<< QString("The serial port is open: ") <<portnameStr;
            configSetEnable(false);
        }
    }
    else {
    
         ui->pushButton_operate->setText("OPEN");
         serial->close();
         configSetEnable(true);
    }
}

//
void MainWindow::on_pushButton_send_clicked()
{
    
    // Simple text box with  toPlainText()  Take the content of the text box  toUtf8  Is converted to utf8 Byte stream in format  
    QByteArray data = ui->textEdit_send->toPlainText().toUtf8();
    serial->write(data);
}

void MainWindow::on_pushButton_clearRcv_clicked()
{
    
    ui->textEdit_rcv->clear();
}

void MainWindow::on_pushButton_clearSend_clicked()
{
    
    ui->textEdit_send->clear();
}

mainwindow.h :

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <QSerialPort>
#include <QSerialPortInfo>

QT_BEGIN_NAMESPACE
namespace Ui {
     class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void configSetEnable(bool b);
    void initConfig();

private slots:
    void serial_readyRead();
    //updata port number
    void updataPortNum();
    void on_pushButton_operate_clicked();
    void on_pushButton_send_clicked();
    void on_pushButton_clearRcv_clicked();
    void on_pushButton_clearSend_clicked();

private:
    Ui::MainWindow *ui;
    QSerialPort *serial;
    bool isSerialOpen;
};
#endif // MAINWINDOW_H

myComboBox.cpp and myComboBox.h Omit

This version is only the simplest serial port program , Compared with the normal serial port assistant , The lack of hex send out 、 Time stamp 、 Regularly send 、 File saving, etc . Just for learning Qt Weiget Serial port use , It will be improved slowly in the future , Can also use QT Quick To write a serial assistant .

【 Reference resources 】

QT in ui Interface controls QComboBox Implement mouse click events

QT5 A serial port programming, —— Write a simple host computer


GitHub Address :     QWidgetPro , Select subproject QSerialAssistant .pro

QT For other articles, please click here :     QT QUICK QML Learning notes

原网站

版权声明
本文为[Penguins on the volcano]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203020622151783.html