做者:zzssdd2html
E-mail:zzssdd2@foxmail.comc++
開發環境:Qt5.12.10 + MinGWapp
實現的功能socket
涉及的知識點ide
QSerialPort
類的使用QTime
類的使用QTextEdit
、QCheckBox
、QPushButton
、QLabel
的使用下面開始逐步講解以上列舉的功能實現函數
在《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.
若須要將接收到的數據以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 returnstrue
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"
有時爲了便於觀察數據收發時間,須要在數據前插入時間戳顯示。使用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.
使用一個quint32類型數據對每次接收數據長度進行累加,記錄接收數據總數,而後將數據更新到ui界面:
dataTotalRx += bytedata.length(); ui->RxCnt_label->setText(QString::number(dataTotalRx));
以上功能完成後將數據顯示到接收框中(爲了區分不一樣顯示格式,作了不一樣的顏色顯示)。完整的數據接收功能展現以下:
/* 函 數: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)
當清除接收
按鍵點擊後,會清除接收框顯示的內容以及接收計數。使用QPushButton的點擊信號槽實現以下:
/* 函 數:on_ClearRx_Bt_clicked 描 述:清除接收按鍵點擊信號對應的槽函數 輸 入:無 輸 出:無 */ void Widget::on_ClearRx_Bt_clicked() { ui->Receive_TextEdit->clear(); ui->RxCnt_label->setText(QString::number(0)); dataTotalRxCnt = 0; }
本篇文章主要是講述如何對串口數據進行接收和顯示。除了上面列出的主要功能外,還須要瞭解各個控件的操做方法,好比QTextEdit文本的添加、QLabel文本的設置等。還有就是QT中基本的數據類型的數據使用,好比QString、QBytArray等。