QT串口助手(三):數據接收

做者:zzssdd2html

E-mail:zzssdd2@foxmail.comc++

1、前言

開發環境:Qt5.12.10 + MinGWapp

實現的功能socket

  • 串口數據的接收
  • ascii字符形式顯示與hex字符形式顯示
  • 時間戳的顯示
  • 接收數據的統計與顯示
  • 接收清零

涉及的知識點ide

  • QSerialPort類的使用
  • 數據格式的轉換
  • QTime類的使用
  • 控件QTextEditQCheckBoxQPushButtonQLabel的使用

2、功能實現

下面開始逐步講解以上列舉的功能實現函數

2.一、數據讀取

《QT串口助手(二):參數配置》中已經實現了串口參數的配置,參數配置完成後就能夠開啓串口的數據接收功能了。在QT中的QSerialPort類繼承自QIODevice類,因此可使用QIODevice的readyRead()信號來觸發數據的接收,在槽函數中實現數據的讀取與處理。信號槽鏈接以下:oop

/* 接收數據信號槽 */
connect(serial, &QSerialPort::readyRead, this, &Widget::SerialPortReadyRead_slot);

補充:ui

[signal]void QIODevice::readyRead()

This signal is emitted once every time new data is available for reading from the device's current read channel. It will only be emitted again once new data is available, such as when a new payload of network data has arrived on your network socket, or when a new block of data has been appended to your device.this

readyRead() is not emitted recursively; if you reenter the event loop or call waitForReadyRead() inside a slot connected to the readyRead() signal, the signal will not be reemitted (although waitForReadyRead() may still return true).spa

Note for developers implementing classes derived from QIODevice: you should always emit readyRead() when new data has arrived (do not emit it only because there's data still to be read in your buffers). Do not emit readyRead() in other conditions.

當有收到新數據信號時,就會執行槽函數裏面的數據讀取功能:

/*讀取串口收到的數據*/
QByteArray bytedata = serial->readAll();

補充:

QByteArray QIODevice::readAll()

Reads all remaining data from the device, and returns it as a byte array.

This function has no way of reporting errors; returning an empty QByteArray can mean either that no data was currently available for reading, or that an error occurred.

2.二、數據轉換

若須要將接收到的數據以HEX格式顯示,則須要對接收到的數據進行如下處理:

/*將數據轉換爲hex格式並以空格分隔->去掉頭尾空白字符->轉換爲大寫形式*/
framedata = bytedata.toHex(' ').trimmed().toUpper();

補充:

QByteArray QByteArray::toHex(char separator) const

This is an overloaded function.

Returns a hex encoded copy of the byte array. The hex encoding uses the numbers 0-9 and the letters a-f.

If separator is not '\0', the separator character is inserted between the hex bytes.

Example:

QByteArray macAddress = QByteArray::fromHex("123456abcdef");
macAddress.toHex(':'); // returns "12:34:56:ab:cd:ef"
macAddress.toHex(0);   // returns "123456abcdef"

This function was introduced in Qt 5.9.

QByteArray QByteArray::trimmed() const

Returns a byte array that has whitespace removed from the start and the end.

Whitespace means any character for which the standard C++ isspace() function returns true in the C locale. This includes the ASCII characters '\t', '\n', '\v', '\f', '\r', and ' '.

Example:

QByteArray ba("  lots\t of\nwhitespace\r\n ");
ba = ba.trimmed();
// ba == "lots\t of\nwhitespace";

Unlike simplified(), trimmed() leaves internal whitespace alone.

QByteArray QByteArray::toUpper() const

Returns an uppercase copy of the byte array. The bytearray is interpreted as a Latin-1 encoded string.

Example:

QByteArray x("Qt by THE QT COMPANY");
QByteArray y = x.toUpper();
// y == "QT BY THE QT COMPANY"

2.三、添加時間戳

有時爲了便於觀察數據收發時間,須要在數據前插入時間戳顯示。使用QTime類中的方法能夠獲取當前系統的時間(精確到ms),對數據處理以下:

/*在數據前插入時間戳:[時:分:秒:毫秒]:RX -> 數據*/
framedata = QString("[%1]:RX -> %2").arg(QTime::currentTime().toString("HH:mm:ss:zzz")).arg(framedata);

補充:

[static]QTime QTime::currentTime()

Returns the current time as reported by the system clock.

Note that the accuracy depends on the accuracy of the underlying operating system; not all systems provide 1-millisecond accuracy.

Furthermore, currentTime() only increases within each day; it shall drop by 24 hours each time midnight passes; and, beside this, changes in it may not correspond to elapsed time, if a daylight-saving transition intervenes.

2.四、接收計數

使用一個quint32類型數據對每次接收數據長度進行累加,記錄接收數據總數,而後將數據更新到ui界面:

dataTotalRx += bytedata.length();
ui->RxCnt_label->setText(QString::number(dataTotalRx));

2.五、數據顯示

以上功能完成後將數據顯示到接收框中(爲了區分不一樣顯示格式,作了不一樣的顏色顯示)。完整的數據接收功能展現以下:

/*
    函   數:SerialPortReadyRead_slot
    描   述:readyRead()信號對應的數據接收槽函數
    輸   入:無
    輸   出:無
*/
void Widget::SerialPortReadyRead_slot()
{
    QString framedata;
    /*讀取串口收到的數據*/
    QByteArray bytedata = serial->readAll();

    /*數據是否爲空*/
    if (!bytedata.isEmpty())
    {
        if(ui->HexDisp_checkBox->isChecked())
        {
            /*hex顯示*/
            framedata = bytedata.toHex(' ').trimmed().toUpper();
            ui->Receive_TextEdit->setTextColor(QColor(Qt::green));
        }
        else
        {
            /*ascii顯示*/
            framedata = QString(bytedata);
            ui->Receive_TextEdit->setTextColor(QColor(Qt::magenta));
        }
        
        /*是否顯示時間戳*/
        if (ui->TimeDisp_checkBox->isChecked()) 
        {
            framedata = QString("[%1]:RX -> %2").arg(QTime::currentTime().toString("HH:mm:ss:zzz")).arg(framedata);
            ui->Receive_TextEdit->append(framedata);
        }
        else
        {
            ui->Receive_TextEdit->insertPlainText(framedata);
        }
        
        /*更新接收計數*/
        dataTotalRxCnt += bytedata.length();
        ui->RxCnt_label->setText(QString::number(dataTotalRxCnt));
    }
}

演示效果以下:

補充:

QColor::QColor(Qt::GlobalColor color)

This is an overloaded function.

Constructs a new color with a color value of color.

enum Qt::GlobalColor

Qt's predefined QColor objects:

Constant Value Description
Qt::white 3 White (#ffffff)
Qt::black 2 Black (#000000)
Qt::red 7 Red (#ff0000)
Qt::darkRed 13 Dark red (#800000)
Qt::green 8 Green (#00ff00)
Qt::darkGreen 14 Dark green (#008000)
Qt::blue 9 Blue (#0000ff)
Qt::darkBlue 15 Dark blue (#000080)
Qt::cyan 10 Cyan (#00ffff)
Qt::darkCyan 16 Dark cyan (#008080)
Qt::magenta 11 Magenta (#ff00ff)
Qt::darkMagenta 17 Dark magenta (#800080)
Qt::yellow 12 Yellow (#ffff00)
Qt::darkYellow 18 Dark yellow (#808000)
Qt::gray 5 Gray (#a0a0a4)
Qt::darkGray 4 Dark gray (#808080)
Qt::lightGray 6 Light gray (#c0c0c0)
Qt::transparent 19 a transparent black value (i.e., QColor(0, 0, 0, 0))
Qt::color0 0 0 pixel value (for bitmaps)
Qt::color1 1 1 pixel value (for bitmaps)

2.六、清除接收

清除接收按鍵點擊後,會清除接收框顯示的內容以及接收計數。使用QPushButton的點擊信號槽實現以下:

/*
    函   數:on_ClearRx_Bt_clicked
    描   述:清除接收按鍵點擊信號對應的槽函數
    輸   入:無
    輸   出:無
*/
void Widget::on_ClearRx_Bt_clicked()
{
    ui->Receive_TextEdit->clear();
    ui->RxCnt_label->setText(QString::number(0));
    dataTotalRxCnt = 0;
}

3、總結

本篇文章主要是講述如何對串口數據進行接收和顯示。除了上面列出的主要功能外,還須要瞭解各個控件的操做方法,好比QTextEdit文本的添加、QLabel文本的設置等。還有就是QT中基本的數據類型的數據使用,好比QStringQBytArray等。

相關文章
相關標籤/搜索