QT project actual combat serial debugging assistant

table of Contents

I. Introduction

1. Extended reading about character set encoding

2. Some summary about character encoding

2. Function and effect

1. Effect

2. Function

Three, the realization process

1. Create QMainWindow window and UI design

2. Code implementation

1. How to associate signals and slots

2. File sending and file saving

3. Save configuration information

4. Conversion between characters and hexadecimal coded characters

3. Project package release

1. Use QT's own windeployqt.exe to package

2. Use HM NIS Edit editor and NSIS compiler for deeper packaging

Four, functional test


I. Introduction

Here is a small serial debugging assistant software written by Amway. It is written in QT5.5 . It can be used normally under Windows. It has not been tested under Linux environment. Garbled characters may appear because the character encoding under Windows environment is ANSI (in ANSI in the Chinese system is GBK encoding), and the character encoding in the Linux environment is UTF-8, and the data sent and received in the debugging assistant is also converted according to GBK encoding. such as:

character

GBK encoding

Unicode encoding

UTF-8

"123 Learning"

31 32 33 D1 A7 CF B0

31 32 33 5B 66 4E 60

31 32 33 E5 AD A6 E4 B9 A0

1. Extended reading about character set encoding

1. Chinese character set encoding query

2. Check the character encoding (UTF-8)

3. Convert between unicode and utf-8

4. What is ANSI code?

5. QT serial port Chinese display problem, Unicode to GBK

6. QT character encoding

2. Some summary about character encoding

1. Characters are a bunch of text symbols. Each country has its own language and characters. How are these characters stored in the computer? Computers are all stored in 01 binary, so just convert these characters into their corresponding and unique binary codes. There are also various encodings, such as English ASCII, Chinese GDB encoding, Japanese Shift-JIS encoding, etc.

2. ASCII code : In the 1960s, the United States formulated a set of character codes to uniformly regulate the relationship between English characters and binary bits. This is called ASCII code. ASCII code specifies 128 characters in total. Encoding. Only occupy the last 7 bits of a byte, and the first 1 bit is uniformly defined as 0

3. GBK code : English encoding with 128 symbols is enough, but for other languages, 128 symbols are not enough, so two bytes are used to represent a Chinese character, so in theory, it can represent up to 256x256=65536 symbol

4. Unicode : There are many encoding methods in the world. The same binary number can be interpreted as different symbols. If you want to open a text file, you must know its encoding method, otherwise it will be interpreted by the wrong encoding method. Garbled characters appear. In order to solve the problem of inconsistency, an international organization came out to formulate an encoding that includes all language characters in the world, which is Unicode encoding. Unicode usually uses two bytes to represent a character. The original English encoding changes from single-byte to double-byte. You only need to fill all high bytes with 0. But Unicode is just a symbol set, it only specifies the binary code of the symbol, but it does not specify how the binary code should be stored. If Unicode is used to represent the advantage of 1 byte of ASCII, it wastes memory, and there are also different storage methods of Unicode.

5. UTF-8 encoding : UTF-8 is the most widely used unicode implementation on the Internet. Other implementations include UTF-16 and UTF-32. One of the biggest features of UTF-8 is that it is a variable-length encoding method. It can use 1 to 6 bytes to represent a symbol, and the byte length varies according to different symbols.

2. Function and effect

1. Effect

Don't talk nonsense, look at the effect first

2. Function

1. Record and save the configuration information of the serial port, so that you can directly use the last configuration when you open it next time

2. Save the data in the serial port receiving area (it can be received by the serial port or sent by the serial port)

3. One key to clear the data in the receiving window and sending window

4. When receiving, you can choose hexadecimal display or character display, you can choose to display the current time and the sent data

5. When sending, you can choose to send regularly, send a new line, and send file data. It should be noted that selecting or not selecting hexadecimal transmission is only the switching of the character display in the transmission area. The data sent is all ANSI-encoded byte data; when hexadecimal is selected, the characters will be converted to ANSI encoding (here is GBK code) display, display characters without checking hexadecimal or convert hexadecimal data into characters according to ANSI code

6. It can display the current serial port status, the number of bytes sent, the number of bytes received, and the current time

Three, the realization process

1. Create QMainWindow window and UI design

After creation, add QT += serialport in the .pro project management file so that the serial port can be used

2. Code implementation

Source connection: https://github.com/denghengli/qt_study/tree/master/17_SerialPort

Focus on:

1. How to associate signals and slots

method one:

0) If it is a custom signal, it needs to be declared in .h

1) Declare the slot function in .h

2) Implement slot function in .cpp

3) Use connect to connect the signal and the slot function:

QObject::connect(ui->pushbutton,SIGNAL( clicked() ),this,SLOT( on_pushBuuton_clicked() );

Method Two:

In the .ui file, right-click the button, select the "go to slot" option, select the signal "clicked", and the stand-alone OK button. The system automatically generates slot function declarations and definitions, and establishes internal mapping. Just write the function of the slot function in the slot function body, and add the statement as step 2 in method 1.

Method three:

In the .ui interface, select the "change signal/slot" option, click "+" to add a new slot function, confirm to complete the addition of the slot function, and finally repeat steps 1 and 2 in Method 1 to complete the slot function declaration and definition.

2. File sending and file saving

Through the file dialog box provided by the QFileDialog class, to select the file to be sent and the newly saved file

openfile_path = QFileDialog::getOpenFileName(this, "打开文件", "", "Text File(*.txt)"); 
savefile_path = QFileDialog::getSaveFileName(this,"另存为", savefile_path, "Text File(*.txt)");

3. Save configuration information

Every time after configuring the serial port, baud rate, stop bit, etc., when opening the serial port, save the configuration information in the form of key-value to a predetermined file through the QSettings class; also read it first every time the software is opened Take the data of this configuration file, and then set the serial port

//创建ini配置文件
void SerialPort::configiniInit()
{
    iniPath = new QDir;
    iniFilename = iniPath->currentPath() + "/SerialPort.ini";
    //构造一个QSettings对象,用于访问存储在名为iniFilename的文件中的设置。如果文件不存在,就创建它
    configini = new QSettings(iniFilename, QSettings::IniFormat);
}

//读取ini配置文件,设置下拉框的项目
void SerialPort::configiniRead()
{
    configini->beginGroup("SETUP");
    int i_port = configini->value("COM").toInt();
    int i_baudrate = configini->value("baudrate").toInt();
    int i_databit = configini->value("databit").toInt();
    int i_checkbit = configini->value("checkbit").toInt();
    int i_stopbit = configini->value("stopbit").toInt();
    configini->endGroup();

    ui->CB_port->setCurrentIndex(i_port);
    ui->CB_baudrate->setCurrentIndex(i_baudrate);
    ui->CB_databit->setCurrentIndex(i_databit);
    ui->CB_checkbit->setCurrentIndex(i_checkbit);
    ui->CB_stopbit->setCurrentIndex(i_stopbit);
}

//写ini配置文件,将下拉框的项目索引写入ini文件
void SerialPort::configiniWrite()
{
    configini->beginGroup("SETUP");
    configini->setValue("COM", ui->CB_port->currentIndex());
    configini->setValue("baudrate", ui->CB_baudrate->currentIndex());
    configini->setValue("databit", ui->CB_databit->currentIndex());
    configini->setValue("checkbit", ui->CB_checkbit->currentIndex());
    configini->setValue("stopbit", ui->CB_stopbit->currentIndex());
    configini->endGroup();
}

4. Conversion between characters and hexadecimal coded characters

Don't confuse it, it is the conversion between characters and ANSI (here GBK) hexadecimal code characters ;

For example: "123 Learning" <----> "31 32 33 D1 A7 CF B0"

The reason is that the textEdit control displays QString characters and needs to switch between characters and hexadecimal when displaying.

"123 Learning" ----> "31 32 33 D1 A7 CF B0" Steps:

//1、获取发送数据 QString = "123学习"
QString sendstr = ui->textEdit_tx->toPlainText();

//2、"123学习" --> GBK编码:31 32 33 D1 A7 CF B0
QByteArray sendarray = sendstr.toLocal8Bit();//"123学习"在QT中是UTF8编码的,所以这里需要使用toLocal8Bit转成Winds中的GBK编码
//3、GBK编码:31 32 33 D1 A7 CF B0 --> GBK编码字符:"31 32 33 D1 A7 CF B0"
QDataStream out(&sendarray,QIODevice::ReadWrite);    //将字节数组读入
while(!out.atEnd())
{
    qint8 outChar = 0;
    out>>outChar;   //每字节填充一次,直到结束
    QString str = QString("%1").arg(outChar&0xFF,2,16,QLatin1Char('0'));
    str = str.toUpper();
    ui->textEdit_tx->insertPlainText(str + " ");//在当前光标处插入文本
    //返回表示当前可见游标的QTextCursor副本。对返回游标的更改不会影响QTextEdit的游标;使用setTextCursor()更新可见的游标
    QTextCursor cursor = ui->textEdit_tx->textCursor();
    cursor.movePosition(QTextCursor::End);//将光标移动到文档的最后
    ui->textEdit_tx->setTextCursor(cursor);//更新光标
}

"31 32 33 D1 A7 CF B0" ----> "123 Learning" Steps:

//1、获取发送数据 QString = "31 32 33 D1 A7 CF B0"
QString sendstr = ui->textEdit_tx->toPlainText();
QByteArray sendarray;
//2、GBK编码字符:"31 32 33 D1 A7 CF B0" --> GBK编码:31 32 33 D1 A7 CF B0
QStringtoHex(sendarray, sendstr);
//3、GBK编码:31 32 33 D1 A7 CF B0 --> Unicode编码 --> "123学习"
QString str1 = QString::fromLocal8Bit(sendarray);//实现了从本地字符集GBK到Unicode的转换,解决中文显示乱码问题
ui->textEdit_tx->setText(str1);

You can see that the QStringtoHex(QByteArray& sendData,QString str) function is more critical , but it is also relatively simple to implement

char SerialPort::ConvertHexChar(char c)
{
    if(c>='a'&&c<='f'){
        return c-'a'+10;
    }
    else if(c>='A'&&c<='F'){
        return c-'A'+10;
    }
    else if(c>='0'&&c<='9'){
        return c-'0';
    }
    else{
        return -1;
    }
}
//"31 32 33 D1 A7 CF B0" --> 31 32 33 D1 A7 CF B0
void SerialPort::QStringtoHex(QByteArray& sendData,QString str)
{
    char hstr,lstr,hdata,ldata;
    int len = str.length();
    int sendnum = 0;
    QByteArray temp;
    temp.resize(len/2);//设置大小,len/2会大于实际16进制字符
    
    for(int i=0;i<len;)
    {
        //QString转QByteArray的方法,Latin1代表ASCII。'3' --> 3
        hstr = str[i].toLatin1();
        if(hstr == ' '){
            ++i; continue;
        }
        if(++i >= len) break;
        lstr = str[i].toLatin1();

        hdata = ConvertHexChar(hstr);
        ldata = ConvertHexChar(lstr);
        if(-1 == hdata || -1 == ldata)
            break;
        ++i;
        temp[sendnum] = hdata<<4|ldata;
        sendnum++;
    }
    sendData.reserve(sendnum);//重新调整大小
    sendData = temp.left(sendnum);//返回一个 字节数组,其中包含这个字节数组最左边的len字节。去掉多余字符
}

3. Project package release

1. Use QT's own windeployqt.exe to package

1. Select release and build the project

2. Copy the .exe file to any path and package it so that it can be run on any computer that does not have the QT environment installed. Before packaging, first make sure that there is windeployqt.exe in the QT installation directory.

3. Open the terminal and enter the .exe directory (shortcut: in the folder, click on the blank space, shift+right click, and select "open window here"), and enter the windeployqt.exe file

4. After the generation is successful, some files will be generated in the current directory. Copy this folder to any computer without a QT environment to run

2. Use HM NIS Edit editor and NSIS compiler for deeper packaging

1. First use QT's own windeployqt.exe to package to generate executable files and required dynamic libraries

2. Download and install the two softwares NSIS and NIS Edit

3. According to the steps of using the NIS Edit installation wizard , package the packaged file of windeployqt.exe to generate a Setup.exe installation wizard file; when using NIS EDIT to install, there is a point that needs attention, in selecting the application file When, choose the folder that needs to be packaged

After completion, you can install and use the serial debugging assistant through this Setup.exe . When installing Setup.exe , follow the prompts and the next step is fine . Is it improved like this? Haha

Four, functional test

1. Download a virtual serial port tool. I downloaded VSDP . Of course, others are okay. As long as the serial port can be virtualized locally, as shown in the figure below, COM1 and COM2 can be interconnected; "Add pair" adds a new virtual serial port

2. Open COM2 with serialport, and use a serial debugging assistant (XCOM here) to open COM1. It is ok to test sending data to each other

 

Guess you like

Origin blog.csdn.net/m0_37845735/article/details/108655012