• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • QtQuick串口編程Demo

    標簽: QtQuick  QML

    一、目標:

    實現QtQuick界面,操控串口通信,進行串口數據的接收和發送


    二、核心思想:

    利用Qt庫的QSerialPort類,使用C++實現串口數據的邏輯通信,并接受QtQuick界面的參數設置,在QML中調用C++實現的函數進行實際的數據收發

    (QML與C++混合編程)


    三、具體實現:

    (1)C++中的邏輯實現

    首先看serialport.h文件

    #ifndef SERIALPORT_H
    #define SERIALPORT_H
    
    #include <QObject>
    #include <QSerialPort>
    
    class SerialPort : public QObject
    {
        Q_OBJECT
    public:
        explicit SerialPort(QObject *parent = nullptr);
        ~SerialPort();
    
        Q_INVOKABLE bool serialConnect(QString port,QString baudrate,QString databits,QString parity,QString stopbits);
        Q_INVOKABLE QString serialRead();
        Q_INVOKABLE bool serialWrite(QString sendStr);
    
    signals:
    
    public slots:
    
    private:
        QSerialPort *m_serial;
    };
    
    #endif // SERIALPORT_H

    其中,注冊到QML環境中的類必須繼承自QObject,在類中聲明“Q_OBJECT”才能在C++中定義信號和槽,需要注冊到QML環境中的,變量屬性加關鍵字“Q_PROPERTY”,函數方法加關鍵字“Q_INVOKABLE”,定義了一個QSerialPort的對象,將在后續連接和通信中實現

    serialport.cpp

    #include "serialport.h"
    
    SerialPort::SerialPort(QObject *parent) : QObject(parent)
    {
        m_serial = new QSerialPort;
    }
    
    bool SerialPort::serialConnect(QString port,QString baudrate,QString databits,QString parity,
                                   QString stopbits)
    {
        m_serial->setPortName(port);
        if(!m_serial->open(QIODevice::ReadWrite))
        {
            printf("Open Error");
            return 0;
        }
    
        switch (baudrate.toInt()) {
        case 4800:
            m_serial->setBaudRate(QSerialPort::Baud4800);
            break;
        case 9600:
            m_serial->setBaudRate(QSerialPort::Baud9600);
            break;
        case 115200:
            m_serial->setBaudRate(QSerialPort::Baud115200);     //設置波特率為115200
            break;
        default:
            printf("BaudRate Error");
            return 0;
        }
    
        switch (databits.toInt()) {
        case 6:
            m_serial->setDataBits(QSerialPort::Data6);
            break;
        case 7:
            m_serial->setDataBits(QSerialPort::Data7);
            break;
        case 8:
            m_serial->setDataBits(QSerialPort::Data8);          //設置數據位8
            break;
        default:
            printf("DataBits Error");
            return 0;
        }
    
        switch (parity.toInt()) {
        case 0:
            m_serial->setParity(QSerialPort::NoParity);         //校驗位設置為0
            break;
        case 2:
            m_serial->setParity(QSerialPort::EvenParity);
            break;
        case 3:
            m_serial->setParity(QSerialPort::OddParity);
            break;
        default:
            printf("Parity Error");
            return 0;
        }
    
        switch (stopbits.toInt()) {
        case 1:
            m_serial->setStopBits(QSerialPort::OneStop);        //停止位設置為1
            break;
        case 2:
            m_serial->setStopBits(QSerialPort::TwoStop);
            break;
        case 3:
            m_serial->setStopBits(QSerialPort::OneAndHalfStop);
            break;
        default:
            printf("StopBits Error");
            return 0;
        }
    
        m_serial->setFlowControl(QSerialPort::NoFlowControl);//設置為無流控制
        return 1;
    }
    
    QString SerialPort::serialRead()
    {
        return m_serial->readAll();
    }
    
    bool SerialPort::serialWrite(QString sendStr)
    {
        if(m_serial->write(sendStr.toLatin1().data(),strlen(sendStr.toLatin1().data())))
            return 1;
        else
            return 0;
    }
    
    SerialPort::~SerialPort()
    {
        if(m_serial->isOpen())
        {
            m_serial->clear();
            m_serial->close();
        }
        m_serial->deleteLater();
    }

    與傳統Qt中使用的函數一致,其中serialConnect函數中,接受Qt界面的參數設置,先打開串口,然后通過switch匹配,分別設置串口通信的串口名稱、波特率、數據位、校驗位、停止位


    (2)將C++中的類注冊到QML中

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include "serialport.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
    
        qmlRegisterType<SerialPort>("an.qt.mySerialPort",1,0,"SerialPort");
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    關鍵在中間的一句使用qmlRegisterType進行注冊,尖括號中為我們前面定義的新類名字,小括號中分別為import將要導入的名稱,主、次版本號,QML中所能使用的對象名稱為雙引號中的SerialPort


    (3)在QML中調用C++的邏輯實現

    import QtQuick 2.0
    import QtQuick.Controls 2.3
    import QtQuick.Layouts 1.3
    import an.qt.mySerialPort 1.0
    
    Page{
       SerialPort{
           id:serialport;
       }
    
       header: ToolBar{
           RowLayout{
               anchors.fill: parent
               Text{
                   text: qsTr("SerialPort客戶端")
    
                   font.pointSize: 20
                   horizontalAlignment: Qt.AlignHCenter
                   Layout.fillWidth: true
               }
           }
       }
    
       GridLayout{
           id:grid
           anchors.verticalCenter: parent.verticalCenter;
           anchors.left: parent.left;
           anchors.leftMargin: 10;
    
           rows:6;
           rowSpacing: 5;
           columns: 2;
           columnSpacing: 5
    
           Label{
               text:qsTr("串口")
           }
           ComboBox{
               id:port;
               model: ["COM1","COM2","COM3"];
           }
    
           Label{
               text:qsTr("波特率")
           }
           ComboBox{
               id:baudrate;
               model: ["4800","9600","115200"];
           }
    
           Label{
               text:qsTr("數據位")
           }
           ComboBox{
               id:databits
               model: ["6","7","8"];
           }
    
           Label{           
               text:qsTr("校驗位")
           }
           ComboBox{
               id:parity
               model: ["0","2","3"];
           }
    
           Label{
               text:qsTr("停止位")
           }
           ComboBox{
               id:stopbits
               model: ["1","2","3"];
           }
    
           Button{
               text: qsTr("打開串口")
               highlighted: true
               Layout.columnSpan: 2;
               onClicked: {
                   serialport.serialConnect(port.currentText,baudrate.currentText,
                      databits.currentText,parity.currentText,stopbits.currentText);
               }
           }
       }
    
        ColumnLayout{
            anchors.left: grid.right
            anchors.leftMargin: 60;
            anchors.verticalCenter: parent.verticalCenter
            spacing: 5
            TextArea{
                id:receive;
                Layout.preferredWidth: 200;
                Layout.preferredHeight: 200;
                text: qsTr("Receive:")
                readOnly: true;
                background: Rectangle{
                    color: "gray"
                }
            }
            Button{
                text: qsTr("接收數據")
                highlighted: true;
                onClicked: {
                    receive.append(serialport.serialRead());
                }
            }
    
            TextField{
                id:send;
                Layout.preferredWidth: 200
            }
    
            Button{
                text:qsTr("發送數據")
                highlighted: true
                onClicked: {
                    serialport.serialWrite(send.text)
                }
            }
        }
    }
    注意前幾行的導入方法“import an.qt.mySerialPort 1.0”,Page前幾行中定義了我們將要使用的對象的id,在按鈕槽函數中調用對象id所包含的C++方法


    四、運行結果:



    五、補充:

    本界面風格使用的谷歌Style=Material,該風格定義在qtquickcontrols2.conf配置文件中

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

    智能推薦

    串口編程案例

    前提準備 虛擬串口 串口調試助手 其他資源 模擬COM1串口發送信息到COM2接收 首先、下載虛擬串口進行安裝,安裝完后打開軟件(漢化過程忽略) 右鍵打開計算機–>管理–>設備管理器–>端口 打開VS,新建項目(Windows 應用程序) 下載串口調試助手,打開 用串口調試助手發送,效果如圖: 簡單串口編程結束!...

    比特說串口編程

    要說一種植物,從種子發芽開始.要說計算機,從源頭開始.   在1.X系列的文章中,我們從最開始的燈泡的例子開始,一步步深入,知道了CPU是怎么工作的,配合內存可以自動工作。   前面的內容基本上是CPU工作原理的完整輪廓了。   我們知道現在使用的各種形態的計算機除了CPU還有很多別的設備,這些所有的設備都不在CPU里面,都是外部設備,簡稱:外設。常見外設有:鍵盤,鼠...

    七、Linux串口編程

    Linux下的串口編程過程如下(我就不給大家再講串口是什么了,不懂得朋友自行補上串口相關知識): 目錄 一、打開串口 二、初始化串口 1、 串口的初始化結構介紹 2、串口的初始化常用函數介紹  函數 tcgetattr 波特率相關的函數 cfsetispeed 和 cfsetospeed、cfgetispeed 、cfgetospeed 函數 tcflush 函數 tcseta...

    樹莓派串口編程

    串口通信通常用在多機通信中 比如樹莓派和語言模塊的通信 數據在T和R之間通信,這時全雙工的 全雙工:兩個人互相罵 半雙工: 講話的時候另一個人閉嘴 通信要求:1、語言相通 ——》數據格式 2、語速正常 ——》波特率 比如用串口使用樹莓派時,選擇了115200。 數據位,停止位,奇偶校驗位就是數據格式 如果不寫驅動,就要用到wiringPi 參考如下 ...

    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_...

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