QT串口助手(二):參數配置

做者:zzssdd2c++

E-mail:zzssdd2@foxmail.com框架

1、前言

開發環境:Qt5.12.10 + MinGW函數

主要實現功能字體

  • 串口參數的配置:波特率數據位中止位校驗位
  • 本機串口設備的查詢與添加顯示
  • 串口設備的手動更新與打開關閉

涉及的知識點ui

  • 串口類QSerialPortQSerialPortInfo的使用
  • 自定義波特率的實現
  • QComboBox下拉列表自適應文本長度顯示
  • 控件QPushButtonQComboBox的使用

2、功能實現

下面開始逐步講解以上列舉的功能this

2.一、串口設備的查詢添加

建立一個串口設備信息列表和串口設備號列表,遍歷本機可用串口而後添加到列表中,將設備信息列表顯示在對應的QComboBox控件中,設備號列表用來後面打開串口設備使用。code

/* 遍歷可用串口設備 */
QStringList SerialPort_Name;
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
    SerialPort_Name << info.portName()+':'+info.description();
    serialDevice << info.portName();
}
/* 添加到串口設備顯示框 */
ui->SerialNum_Box->addItems(SerialPort_Name);

2.二、下拉列表自適應

此時已經將串口設備信息添加到下拉框中了,可是下拉框此時是固定長度,若是串口設備信息比較長則沒法顯示徹底(以省略號展現),那麼就須要實現下拉框根據設備信息字符串長度適配功能。原理就是遍歷列表中全部設備信息字符串的長度,找出最大值而後將下拉框長度設置到能徹底顯示最大長度字符串。對象

/* 獲取最長字符串 */
int maxlen = 0;
for (int index = 0; index < ui->SerialNum_Box->count(); index++)
{
    if (ui->SerialNum_Box->itemText(index).length() > maxlen)
    {
        maxlen = ui->SerialNum_Box->itemText(index).length();
    }
}
/*獲取字體磅值轉換爲像素值*/
int fontsize = ui->SerialNum_Box->font().pointSize();//獲取字體的磅值
ui->SerialNum_Box->view()->setFixedWidth(fontsize * maxlen * 0.75);//設置像素值

這裏涉及字體磅與像素對應關係,由於setFixedWidth函數參數單位是像素。下面列出字號不一樣單位對照表:blog

中文字號 英文字號(磅) 毫米 像素
1英寸 72pt 25.30mm 95.6px
大特號 63pt 22.14mm 83.7px
特號 54pt 18.97mm 71.7px
初號 42pt 14.82mm 56px
小初 36pt 12.70mm 48px
一號 26pt 9.17mm 34.7px
小一 24pt 8.47mm 32px
二號 22pt 7.76mm 29.3px
小二 18pt 6.35mm 24px
三號 16pt 5.64mm 21.3px
小三 15pt 5.29mm 20px
四號 14pt 4.94mm 18.7px
小四 12pt 4.23mm 16px
五號 10.5pt 3.70mm 14px
小五 9pt 3.18mm 12px
六號 7.5pt 2.56mm 10px
小六 6.5pt 2.29mm 8.7px
七號 5.5pt 1.94mm 7.3px
八號 5pt 1.76mm 6.7px

由上表可知:1inch = 72pt,那麼1pt = 1 / 72(inch),咱們使用的9pt字號就是9 * (1 / 72) = 1 / 8(inch).繼承

DPI(dots per inch)表示每英寸可以打印的格點數量(能夠理解爲像素點數),這個值通常默認值爲96。在小字體模式下分辨率是96DPI(大字體模式下分辨率是120DPI),也就是說每英寸能顯示96個像素,由此能夠算出咱們使用的9pt字號對應像素:96dpi / (1 / 8)inch = 12px,那麼1px = 9pt / 12px = 0.75pt。

添加該功能後先後對比:

2.三、串口參數的配置

這部分功能實現串口參數的配置,主要有波特率、數據位、中止位、校驗位等,根據下拉框選擇的參數進行配置。

/* 設置波特率 */
switch (ui->Bandrate_Box->currentIndex())
{
    case 0:
        serial->setBaudRate(QSerialPort::Baud1200,QSerialPort::AllDirections);
        break;
    case 1:
        serial->setBaudRate(QSerialPort::Baud2400,QSerialPort::AllDirections);
        break;
    case 2:
        serial->setBaudRate(QSerialPort::Baud4800,QSerialPort::AllDirections);
        break;
    case 3:
        serial->setBaudRate(QSerialPort::Baud9600,QSerialPort::AllDirections);
        break;
    case 4:
        serial->setBaudRate(QSerialPort::Baud19200,QSerialPort::AllDirections);
        break;
    case 5:
        serial->setBaudRate(QSerialPort::Baud38400,QSerialPort::AllDirections);
        break;
    case 6:
        serial->setBaudRate(QSerialPort::Baud57600,QSerialPort::AllDirections);
        break;
    case 7:
        serial->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);
        break;
    case 8:
        /*自定義波特率*/
    default:
        break;
}
/* 設置數據位 */
switch (ui->Databit_Box->currentIndex()) {
    case 0:
        serial->setDataBits(QSerialPort::Data5);
        break;
    case 1:
        serial->setDataBits(QSerialPort::Data6);
        break;
    case 2:
        serial->setDataBits(QSerialPort::Data7);
        break;
    case 3:
        serial->setDataBits(QSerialPort::Data8);
        break;
    default:
        break;
}
/* 設置中止位 */
switch (ui->Stopbit_Box->currentIndex()) {
    case 0:
        serial->setStopBits(QSerialPort::OneStop);
        break;
    case 1:
        serial->setStopBits(QSerialPort::OneAndHalfStop);
        break;
    case 2:
        serial->setStopBits(QSerialPort::TwoStop);
        break;
    default:
        break;
}
/* 設置校驗位 */
switch (ui->Parity_Box->currentIndex()) {
    case 0:
        serial->setParity(QSerialPort::NoParity);
        break;
    case 1:
        serial->setParity(QSerialPort::EvenParity);
        break;
    case 2:
        serial->setParity(QSerialPort::OddParity);
        break;
    default:
        break;
}
/* 設置流控制 */
serial->setFlowControl(QSerialPort::NoFlowControl);

2.四、自定義波特率

在QT的源碼文件qserialport.h中枚舉了經常使用的波特率:

enum BaudRate {
        Baud1200 = 1200,
        Baud2400 = 2400,
        Baud4800 = 4800,
        Baud9600 = 9600,
        Baud19200 = 19200,
        Baud38400 = 38400,
        Baud57600 = 57600,
        Baud115200 = 115200,
        UnknownBaud = -1
    };

可是若是沒有列出咱們用到的波特率,那麼就須要實現自定義波特率(好比我之前參與的一個項目就要求串口使用500000bps波特率)。實現方式就是將波特率QComboBox列表最後一項設置爲自定義波特率,當使用自定義波特率時則獲取填寫的自定義值並轉換爲qint32類型數值,而後將該參數設置爲波特率,以下:

qint32 CustomBandrate = ui->Bandrate_Box->currentText().toUInt();
serial->setBaudRate(CustomBandrate, QSerialPort::AllDirections);

這裏須要注意的是波特率列表自定義項以前的都是對應的固定波特率值,若是不是選擇自定義波特率應當設置爲不可編輯狀態,只有選擇自定義波特率時才能夠編輯。這裏使用QComboBox的信號currentIndexChanged觸發槽函數實現該功能:若是選擇了自定義波特率,則將下拉框設爲可編輯,不然設爲不能編輯

/*下拉項改變信號槽:重載函數如有多種不一樣參數類型則使用信號槽鏈接時有必要指定參數類型*/
connect(ui->Bandrate_Box, QOverload<int>::of(&QComboBox::currentIndexChanged),[=](int index){
    if (index == 8) {
        ui->Bandrate_Box->setEditable(true);
        ui->Bandrate_Box->setCurrentText(NULL);
    } else {
        ui->Bandrate_Box->setEditable(false);
    }
});

參數配置列表完成以下:

2.五、串口打開與關閉

串口開關按鈕點擊信號對應的槽函數實現內容以下:

/*
    函   數:on_SerialPortSwitch_Bt_clicked
    描   述:開關串口按鍵點擊槽函數
    輸   入:無
    輸   出:無
*/
void Widget::on_SerialPortSwitch_Bt_clicked()
{
    if (ui->SerialPortSwitch_Bt->text() == "打開")
    {
        /* 建立串口對象 */
        serial = new QSerialPort(this);
        /* 建立接收數據信號槽 */
        connect(serial, &QSerialPort::readyRead, this, &Widget::SerialPortReadyRead_slot);
        /* 設置串口號 */
        QString dev = serialDevice.at(ui->SerialNum_Box->currentIndex());
        serial->setPortName(dev);
        /* 設置波特率 */
        /* 設置數據位 */
        /* 設置中止位 */
        /* 設置校驗位 */
        /* 設置流控制 */
        /* 打開串口 */
        if (serial->open(QIODevice::ReadWrite) != true)
        {
            QMessageBox::critical(this, "提示", "打開失敗");
            return;
        }
        /*標記串口已打開*/
        global_struct.isSerialOpen = true;
        /*設置文本*/
        ui->SerialPortSwitch_Bt->setText("關閉");
    }
    else
    {
        /*關閉並刪除串口對象*/
        serial->close();
        serial->deleteLater();
        /*標記串口已關閉*/
        global_struct.isSerialOpen = false;
        /*設置文本*/
        ui->SerialPortSwitch_Bt->setText("打開");
    }
}

2.六、串口設備的刷新

串口設備刷新按鈕點擊信號對應的槽函數功能實現以下:

/*
    函   數:on_ComFlush_BT_clicked
    描   述:串口設備刷新按鈕槽函數
    輸   入:無
    輸   出:無
*/
void Widget::on_ComFlush_BT_clicked()
{
    ui->SerialNum_Box->clear();
    FindSerialPort();
}

/*
    函   數:FindSerialPort
    描   述:查找串口並添加到QComboBox
    輸   入:無
    輸   出:無
*/
void Widget::FindSerialPort(void)
{
    /* 遍歷可用串口並添加到顯示框 */
    QStringList SerialPort_Name;
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        SerialPort_Name << info.portName()+':'+info.description();
        serialDevice << info.portName();
    }
    ui->SerialNum_Box->addItems(SerialPort_Name);
    /*設置下拉框列表寬度*/
    int maxlen = 0;
    for (int index = 0; index < ui->SerialNum_Box->count(); index++)
    {
        if (ui->SerialNum_Box->itemText(index).length() > maxlen)
        {
            maxlen = ui->SerialNum_Box->itemText(index).length();
        }
    }
    int fontsize = ui->SerialNum_Box->font().pointSize();
    ui->SerialNum_Box->view()->setFixedWidth(fontsize * maxlen * 0.75);
}

3、總結

本篇文章主要是講如何對串口參數進行配置及QComboBox等控件的一些基本操做。除此以外,還應該瞭解必定C++知識,好比類的繼承、函數重載、Lambda表達式等;還有就是應該掌握QT信號槽的使用,由於這是QT框架中很是重要的通訊機制,能夠說使用QT開發必然離不開信號槽的應用。

相關文章
相關標籤/搜索