CSerialPort チュートリアル 4.3.x (4) - QT での CSerialPort の使用

CSerialPort チュートリアル 4.3.x (4) - QT での CSerialPort の使用

環境:

QT: 5.6.3

序文

CSerialPortプロジェクトは、C/C++ に基づく軽量のオープンソース クロスプラットフォーム シリアル ポート クラス ライブラリです。これにより、プラットフォームや複数のオペレーティング システム間でシリアル ポートの読み取りと書き込みを簡単に実現でき、C#、Java、Python、Node.js もサポートされます。等

CSerialPort プロジェクトのオープン ソース プロトコルは、バージョン V3.0.0.171216 以降、GNU Lesser General Public License v3.0を採用しています。

開発者が開発に CSerialPort をより適切に使用できるようにするために、バージョン 4.3.x に基づいた CSerialPort チュートリアル シリーズが特別に作成されました。

CSerialPort プロジェクト アドレス:

QT 完全なサンプル プログラムのアドレス:

  • https://github.com/itas109/CSerialPort/tree/master/examples/CommQT
  • https://gitee.com/itas109/CSerialPort/tree/master/examples/CommQT

1. 新しい QT プロジェクトを作成する

新しい QT プロジェクトを作成します。ソリューション名は CommQT です。

[ファイル] - [新しいファイルまたはプロジェクト] - [アプリケーション(Qt)] - [Qt ウィジェット アプリケーション] - [選択...] - [名前: CommQT]

CommQT ソリューション ディレクトリに CSerialPort ソース コードをダウンロードします。

$ cd CommQT
$ git clone https://github.com/itas109/CSerialPort

ディレクトリ構造は次のとおりです。

D:/CommQT $ tree
.
+--- CommQT.pro
+--- CSerialPort
|   +--- include
|   |   +--- CSerialPort
|   |   |   +--- SerialPort.h
|   |   |   +--- SerialPortInfo.h
|   +--- src
|   |   +--- SerialPort.cpp
|   |   +--- SerialPortBase.cpp
|   |   +--- SerialPortInfo.cpp
|   |   +--- SerialPortInfoBase.cpp
|   |   +--- SerialPortInfoUnixBase.cpp
|   |   +--- SerialPortInfoWinBase.cpp
|   |   +--- SerialPortUnixBase.cpp
|   |   +--- SerialPortWinBase.cpp
+--- main.cpp
+--- mainwindow.cpp
+--- mainwindow.h
+--- mainwindow.ui

2. CommQT.pro に必要な CSerialPort 依存関係を追加します。

CommQT.pro に CSerialPort 依存関係を追加する

#-------------------------------------------------
#
# Project created by QtCreator
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = CommQT
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui

# add by itas109
# 1. headers
INCLUDEPATH += "$$PWD/CSerialPort/include"

# 2. sources
SOURCES += $$PWD/CSerialPort/src/SerialPortBase.cpp
SOURCES += $$PWD/CSerialPort/src/SerialPort.cpp
SOURCES += $$PWD/CSerialPort/src/SerialPortInfoBase.cpp
SOURCES += $$PWD/CSerialPort/src/SerialPortInfo.cpp

win32 {
    SOURCES += $$PWD/CSerialPort/src/SerialPortWinBase.cpp
    SOURCES += $$PWD/CSerialPort/src/SerialPortInfoWinBase.cpp
}

unix {
    SOURCES += $$PWD/CSerialPort/src/SerialPortUnixBase.cpp
    SOURCES += $$PWD/CSerialPort/src/SerialPortInfoUnixBase.cpp
}

# 3. add system libs
win32-msvc*:LIBS += advapi32.lib
win32-msvc*:LIBS += setupapi.lib
win32-g++:LIBS += libsetupapi

# 4. define UNICODE
DEFINES += _UNICODE
# end by itas109

3. QT に CSerialPort コードを追加します。

3.1 CSerialPortのヘッダファイル、継承クラス、受信関数、CSerialPortインスタンスオブジェクトを追加

mainwindow.h ファイル内

  • CSerialPortのヘッダーファイルを追加
  • MainWindow クラスの継承CSerialPortListener
  • 受信機機能の追加onReadEvent(const char *portName, unsigned int readBufferLen)
  • CSerialPortのインスタンスオブジェクトを増やす
  • データを受信するための QPlainTextEdit コントロールを追加します

メインウィンドウ.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

// add by itas109
#include <QPlainTextEdit>

#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortInfo.h"
using namespace itas109;
// end by itas109

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow,public CSerialPortListener // add by itas109
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    // add by itas109
private:
    void onReadEvent(const char *portName, unsigned int readBufferLen);

signals:
    void emitUpdateReceive(QString str);

private slots:
    void OnUpdateReceive(QString str);

private:
    QPlainTextEdit * p_plainTextEditReceive;
    CSerialPort m_serialPort;
    // end by itas109
};

#endif // MAINWINDOW_H

3.2 シリアルポートの関連実装コードを追加

ファイルにmainwindow.cpp追加されました

  • MainWindow::MainWindowCSerialPortのテストコードを追加します。
  • OnReceive 関数の実装を増やす
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // add by itas109
    p_plainTextEditReceive = NULL;
    p_plainTextEditReceive = new QPlainTextEdit();
    this->setCentralWidget(p_plainTextEditReceive);

    std::vector<SerialPortInfo> portNameList = CSerialPortInfo::availablePortInfos();

    if (portNameList.size() > 0)
    {
        p_plainTextEditReceive->moveCursor (QTextCursor::End);
        p_plainTextEditReceive->insertPlainText(QString("First avaiable Port: %1\n").arg(portNameList[0].portName));
    }
    else
    {
        p_plainTextEditReceive->moveCursor (QTextCursor::End);
        p_plainTextEditReceive->insertPlainText("No avaiable Port");
        return;
    }

    connect(this,&MainWindow::emitUpdateReceive,this,&MainWindow::OnUpdateReceive,Qt::QueuedConnection);

    m_serialPort.connectReadEvent(this);

    m_serialPort.init(portNameList[0].portName);

    m_serialPort.open();

    if (m_serialPort.isOpen())
    {
        p_plainTextEditReceive->moveCursor (QTextCursor::End);
        p_plainTextEditReceive->insertPlainText(QString("open %1 success\n").arg(portNameList[0].portName));

        m_serialPort.writeData("itas109", 7);
    }
    else
    {
        p_plainTextEditReceive->moveCursor (QTextCursor::End);
        p_plainTextEditReceive->insertPlainText(QString("open %1 failed\n").arg(portNameList[0].portName));
    }
    // end by itas109
}

MainWindow::~MainWindow()
{
    delete ui;

    // add by itas109
    m_serialPort.disconnectReadEvent();
    // end by itas109
}

// add by itas109
void MainWindow::onReadEvent(const char *portName, unsigned int readBufferLen)
{
    if(readBufferLen > 0)
    {
        char data[1024];
        int recLen = m_serialPort.readData(data,readBufferLen > 1023 ? 1023 : readBufferLen);

        if (recLen > 0)
        {
            data[recLen] = '\0';

            emitUpdateReceive(QString::fromLocal8Bit(data,recLen));
        }
    }
}

void MainWindow::OnUpdateReceive(QString str)
{
    p_plainTextEditReceive->moveCursor (QTextCursor::End);
    p_plainTextEditReceive->insertPlainText(str);
}
// end by itas109

4. 結果

コード内の COM2 に対応するシリアル ポートは RS232 ループバック テスト ハードウェアであるため、対応する結果は次のようになります。
プログラムの開始後、シリアル ポートを初期化して開きCOM2、受信ウィンドウを印刷しopen xxx success、データを送信しitas09、受信ウィンドウを印刷します。itas09

Windows での結果:

First avaiable Port: COM1
open COM1 success
itas109

Linux での結果:

First avaiable Port: /dev/ttyUSB0
open /dev/ttyUSB0 success
itas109

Linux では権限の問題が発生する可能性があります

open port error: Unable to open /dev/ttyUSB0: 权限不够

一時的な解決策:

$ sudo chmod 777 /dev/ttyUSB0

永続的な解決策 (dev は現在のユーザー名です):

$ sudo usermod -aG dialout dev
$ newgrp dialout # 立即生效

ライセンス

CC BY-NC-ND 4.0 に基づくライセンス: 表示 - 非営利使用 - 改変禁止


参照:

  1. https://github.com/itas109/CSerialPort
  2. https://gitee.com/itas109/CSerialPort
  3. https://blog.csdn.net/itas109

おすすめ

転載: blog.csdn.net/itas109/article/details/132389548
おすすめ