• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • QT項目實戰 --- 串口調試助手

    標簽: qt5  c++  

    目錄

    一、前言

    1、關于字符集編碼的延伸閱讀

    2、關于字符編碼幾點的總結

    二、功能與效果

    1、效果

    2、功能

    三、實現過程

    1、創建QMainWindow窗口與UI設計

    2、代碼實現

    1、信號和槽的關聯方式

    2、文件發送和文件保存

    3、配置信息的保存

    4、字符與16進制編碼字符的互相轉換

    3、工程打包發布

    1、使用QT自帶的windeployqt.exe打包

    2、使用HM NIS Edit編輯器與NSIS編譯器更深層次打包

    四、功能測試


    一、前言

    給大家安利一款自己編寫的串口調試助手小軟件,使用QT5.5編寫,在windows下可正常使用,Linux環境下沒測試過,可能會出現亂碼,因為windows環境下的字符編碼是ANSI(在中文系統中ANSI就是GBK編碼),而Linux環境下字符編碼是UTF-8,調試助手中發送和接收的數據也都是按照GBK編碼轉換的。比如:

    字符

    GBK編碼

    Unicode編碼

    UTF-8

    "123學習"

    31 32 33 D1 A7 CF B0

    31 32 33 5B 66 4E 60

    31 32 33 E5 AD A6 E4 B9 A0

    1、關于字符集編碼的延伸閱讀

    1、漢字字符集編碼查詢

    2、查看字符編碼(UTF-8)

    3、unicode和utf-8互轉

    4、ANSI是什么編碼?

    5、QT串口中文顯示問題,Unicode轉GBK

    6、QT字符編碼

    2、關于字符編碼幾點的總結

    1、字符就是一堆文字符號,每個國家都會有自己的語言文字,這些字符在計算機中怎么存儲呢?計算機中都是以01二進制存儲的,把這些字符轉成其對應且唯一的二進制碼不就行了。也就出現了各種編碼,比如英文的ASCII、中文的GDB編碼、日文的Shift-JIS編碼等等

    2、ASCII碼:上個世紀60年代, 美國制定了一套字符編碼, 對英語字符與二進制位之間的關系, 做了統一規定,這被稱為ASCII碼,ASCII碼一共規定了128個字符的編碼。只占用了一個字節的后面7位, 最前面的1位統一規定為0

    3、GBK碼:英語用128個符號編碼就夠了, 但是用來表示其他語言, 128個符號是不夠的,于是就使用兩個字節表示一個漢字, 所以理論上最多可以表示256x256=65536個符號

    4、Unicode:世界上存在著多種編碼方式, 同一個二進制數字可以被解釋成不同的符號,要想打開一個文本文件, 就必須知道它的編碼方式, 否則用錯誤的編碼方式解讀, 就會出現亂碼。為了解決不統一的問題,有個國際組織就出來制定了包含世界上所有語言字符的編碼,這就是Unicode編碼。Unicode通常用兩個字節表示一個字符,原有的英文編碼從單字節變成雙字節,只需要把高字節全部填為0就可以。但是 Unicode只是一個符號集, 它只規定了符號的二進制代碼, 卻沒有規定這個二進制代碼應該如何存儲,如果用Unicode來表示1字節的ASCII優點浪費內存,而且也出現了不同存儲方式的Unicode

    5、UTF-8編碼 :UTF-8就是在互聯網上使用最廣的一種unicode的實現方式. 其他實現方式還包括UTF-16和UTF-32。UTF-8最大的一個特點, 就是它是一種變長的編碼方式. 它可以使用1~6個字節表示一個符號, 根據不同的符號而變化字節長度.

    二、功能與效果

    1、效果

    廢話不多說,先看效果

    2、功能

    1、記錄和保存串口的配置信息,便于下次打開時直接使用上次的配置

    2、保存串口接收區的數據(可以是串口接收的的也可以是串口發送的)

    3、一鍵清除接收窗口和發送窗口的數據

    4、接收時,可以選擇16進制顯示還是字符顯示,可以選擇顯示當前的時間和發送的數據

    5、發送時,可以選擇定時發送以及發送新行,可以發送文件數據。需要注意的是,選擇或不選擇16進制發送只是在發送區字符顯示的切換,發送的數據都是ANSI編碼的字節數據;勾選16進制時就將字符轉成ANSI編碼(這里是GBK編碼)顯示,不勾選16進制就顯示字符或是將16進制數據根據ANSI編碼轉成字符

    6、可以顯示當前的串口狀態、發送的字節數、接收的字節數、當前的時間

    三、實現過程

    1、創建QMainWindow窗口與UI設計

    創建后在 .pro 工程管理文件中添加 QT += serialport,這樣才能使用串口

    2、代碼實現

    源碼連接:https://github.com/denghengli/qt_study/tree/master/17_SerialPort

    劃重點:

    1、信號和槽的關聯方式

    方法一:

    0)如果是自定義的信號,需要在.h中聲明

    1)在.h中聲明槽函數

    2)在.cpp中實現槽函數

    3)使用connect將信號和槽函數進行連接:

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

    方法二:

    在.ui文件中,右擊按鈕,選擇''go to slot''選項,選擇信號"clicked",單機確定按鈕。系統自動生成槽函數聲明和定義,并建立內部映射。只需在槽函數體內編寫槽函數體內編寫槽函數的功能即可,添加語句如方法一中的步驟2.

    方法三:

    在.ui界面,選擇"改變信號/槽"選項,單擊"+"添加新的槽函數,確定完成槽函數的添加,最后重復方法一中的步驟1和步驟2完成槽函數聲明和定義.

    2、文件發送和文件保存

    通過QFileDialog類提供的文件對話框,來選擇要發送的文件和新建保存的文件

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

    3、配置信息的保存

    每一次在配置完串口、波特率、停止位等后,打開串口時,通過QSettings類將這些配置信息以key-value的形式保存到預先規定的文件中;在每次打開軟件時也先讀取這個配置文件的數據,再設置串口

    //創建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、字符與16進制編碼字符的互相轉換

    不要弄混了,是字符ANSI(這里是GBK)16進制編碼字符的互相轉換;

    例如:“123學習” <----> "31 32 33 D1 A7 CF B0"

    原因是,textEdit控件顯示的是QString字符,在顯示時需要在字符和16進制之間切換。

    “123學習” ----> "31 32 33 D1 A7 CF B0" 步驟:

    //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學習” 步驟:

    //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);

    可以看到 QStringtoHex(QByteArray& sendData,QString str)函數比較關鍵,但是實現起來也比較簡單

    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、工程打包發布

    1、使用QT自帶的windeployqt.exe打包

    1、選擇 release,構建工程

    2、將 .exe文件拷貝到任意路徑下,將其進行打包,這樣在任意一臺沒有安裝QT環境的電腦也可以運行,打包前首先要確保QT的安裝目錄下有 windeployqt.exe

    3、打開終端,進入到.exe目錄下(快捷方式:在文件夾中,點擊空白處,shift+右鍵,選擇“在此處打開窗口”),輸入 windeployqt.exe 文件

    4、生成成功后,會在當前目錄下生成一些文件,將此文件夾拷貝到任意沒有QT環境的電腦上也能運行

    2、使用HM NIS Edit編輯器與NSIS編譯器更深層次打包

    1、先使用QT自帶的windeployqt.exe打包,生成可執行文件和需要的動態庫

    2、下載安裝 NSIS 和 NIS Edit 這兩個軟件

    3、根據 NIS Edit安裝向導的使用 步驟,將windeployqt.exe 打包后的文件再打包生成一個 Setup.exe 的安裝向導文件;使用NIS EDIT安裝時,有個需要注意的地方,在選擇應用程序的文件時,要選擇需要打包的文件夾

    完成后就可以通過這個Setup.exe來安裝并使用串口調試助手了。在安裝 Setup.exe 的時候根據提示下一步下一步就可以了。這樣逼格是不是都提高了 哈哈

    四、功能測試

    1、下載一個虛擬串口的工具,我下載的是 VSDP ,當然其他的也行,只要能在本地虛擬出串口就行,如下圖,COM1和COM2就可以互聯了;"Add pair "添加新的虛擬串口

    2、用serialport打開COM2,隨便用一個串口調試助手(我這里用的XCOM)打開COM1,測試互相發送數據都是ok的

     

    版權聲明:本文為m0_37845735原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/m0_37845735/article/details/108655012

    智能推薦

    QT實現串口調試助手(六):頁面布局

    工程源碼:https://github.com/zhangfls/QT_UartAnalysisTool   上一篇: INI文件存取串口信息   之前沒有設置頁面布局,當窗口進行放大縮小時,組件的位置還是保持原樣,這樣很不實用。所以要調整一下頁面和組件布局 QT幾種常見的布局: 下面就用這些布局調整一下組件的位置排布。 1、添加horizontalLayout水平布局,將頁面...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    猜你喜歡

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    統計學習方法 - 樸素貝葉斯

    引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...

    styled-components —— React 中的 CSS 最佳實踐

    https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...

    基于TCP/IP的網絡聊天室用Java來實現

    基于TCP/IP的網絡聊天室實現 開發工具:eclipse 開發環境:jdk1.8 發送端 接收端 工具類 運行截圖...

    精品国产乱码久久久久久蜜桃不卡