开发使用指导

更新时间:
2024-01-24
下载文档

开发使用指导

本节主要介绍 QVSOA 在 Qt 中的使用方法、帮助查看方法以及代码示例。

在 Qt 中使用 QVSOA

安装完 QVSOA 之后,即可在 Qt 工程中使用 QVSOA。下面分别介绍如何在 Qt 的 qmake 和 cmake 工程中使用 VSOA。

在 qmake 工程中使用

  1. 创建一个 Qt qmake 工程 app_qmake

  2. 在工程文件 app_qmake.pro 中添加 QT += vsoa

    QT -= gui
    QT += vsoa
    
    CONFIG += c++11 console
    CONFIG -= app_bundle
    
    # You can make your code fail to compile if it uses deprecated APIs.
    # In order to do so, uncomment the following line.
    # DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    SOURCES += \
        main.cpp
    
    # Default rules for deployment.
    sylixos: target.path = /apps/$${TARGET}
    else: qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
  3. 在源代码中添加头文件 #include <QVsoa>

    #include <QCoreApplication>
    #include <QVsoa>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        return a.exec();
    }
    

在 cmake 工程中使用

  1. 创建一个 Qt cmake 工程 app_cmake

  2. CMakeLists.txt 中引入 QVSOA

    cmake_minimum_required(VERSION 3.14)
    
    project(app_cmake LANGUAGES CXX)
    
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Vsoa REQUIRED)
    find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Vsoa REQUIRED)
    
    add_executable(app_cmake
    main.cpp
    )
    
    target_link_libraries(app_cmake Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Vsoa)
    
    enable_auto_deploy(ON)
    add_deployment_file(app_cmake "apps/${PROJECT_NAME}")
    
  3. 在源代码中添加头文件 #include <QVsoa>

    #include <QCoreApplication>
    #include <QVsoa>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        return a.exec();
    }
    

查看 QVSOA 帮助

查看 QVSOA API

  • 在左侧导航栏单击 帮助,在 Qt 帮助文档界面搜索 “QVSOA” ,单击搜索到的文档目录即可打开对应的文档页面。

  • 开发过程中也可以使用 F1 随时查阅相关内容。

查看 QVSOA 示例

在左侧导航栏单击欢迎,选中示例,搜索“QVSOA” 即可查看 QVSOA 示例。

QVSOA 开发示例

下面以模拟交通信号灯为例介绍 QVSOA 客户端与服务端的开发示例。

客户端示例

创建一个名称为 clientQt Widgets Application 程序。

如下是自动生成的 Qt 窗口程序代码,不需要做任何修改。

// main.cpp
#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.showFullScreen();
    return a.exec();
}

使用 QLabel 绘制信号灯,使用 QVSOA 来与信号灯控制中心 Server 端通信。

// widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>
#include <QVsoa>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

protected:
    // Override the window size change event to modify the size of traffic lights
    void resizeEvent(QResizeEvent *event) override;

private:
    // Three lamps
    QLabel *m_red;
    QLabel *m_green;
    QLabel *m_yellow;
    // VSOA client
    QVsoaClient m_client;
};
#endif // WIDGET_H

如下为主要逻辑,包含了与信号灯控制中心的通信,更改当前显示的状态等操作。

// widget.cpp
#include "widget.h"

#include <QDebug>
#include <QHBoxLayout>
#include <QJsonDocument>
#include <QResizeEvent>
#include <QVariantMap>

// Set the color of the light
static void setColor(QLabel *label, QColor color)
{
    label->setStyleSheet(
        QString("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, "
                "stop:0.9 rgba(%1, %2, %3, %4), stop:1 rgba(255, 255, 255, 0));"
                "color: rgba(255, 255, 255, 255);")
            .arg(color.red())
            .arg(color.green())
            .arg(color.blue())
            .arg(color.alpha()));
}

Widget::Widget(QWidget *parent)
    : QWidget(parent),
      m_client()
{
    // Initialize UI.
    auto hLayout = new QHBoxLayout(this);
    hLayout->setSpacing(0);
    hLayout->setMargin(0);
    setLayout(hLayout);

    m_red = new QLabel(this);
    setColor(m_red, Qt::gray);
    m_red->setAlignment(Qt::AlignCenter);

    m_yellow = new QLabel(this);
    setColor(m_yellow, Qt::gray);
    m_yellow->setAlignment(Qt::AlignCenter);

    m_green = new QLabel(this);
    setColor(m_green, Qt::gray);
    m_green->setAlignment(Qt::AlignCenter);

    hLayout->addWidget(m_red);
    hLayout->addWidget(m_yellow);
    hLayout->addWidget(m_green);

    // Initialize QVSOA client.
    // When we receive a message from the server,
    // we change the color of the light and the countdown
    connect(&m_client, &QVsoaClient::message, [&](QString url, QVsoaPayload payload) {
        if (url == "/light") {
            // The server publishes the message using a string in Json format.
            auto doc       = QJsonDocument::fromJson(payload.param().toLatin1());
            auto msg       = doc.toVariant().toMap();
            // Gets the current color and countdown.
            auto color     = msg.value("color").toString();
            auto countdown = msg.value("countdown").toInt();
            if (color == "red") {
                setColor(m_red, Qt::red);
                m_red->setText(QString::number(countdown));
                setColor(m_green, QColor::fromRgb(0, 255, 0, 75));
                m_green->setText({});
                setColor(m_yellow, QColor::fromRgb(255, 255, 0, 75));
                m_yellow->setText({});
            } else if (color == "green") {
                setColor(m_red, QColor::fromRgb(255, 0, 0, 75));
                m_red->setText({});
                setColor(m_green, Qt::green);
                m_green->setText(QString::number(countdown));
                setColor(m_yellow, QColor::fromRgb(255, 255, 0, 75));
                m_yellow->setText({});
            } else {
                setColor(m_red, QColor::fromRgb(255, 0, 0, 75));
                m_red->setText({});
                setColor(m_green, QColor::fromRgb(0, 255, 0, 75));
                m_green->setText({});
                setColor(m_yellow, Qt::yellow);
                m_yellow->setText(QString::number(countdown));
            }
        }
    });

    // When we successfully connect to the server, we subscribe to the light message.
    connect(&m_client, &QVsoaClient::connected, [&](bool ok, QString info) {
        if (!ok) {
            qDebug() << "Can not connect to VSOA server!";
            return;
        }
        m_client.subscribe("/light");
    });
    m_client.connect2server(QVsoaSocketAddress(AF_INET, "127.0.0.1", 8888), {});
}

Widget::~Widget() {}

void Widget::resizeEvent(QResizeEvent *event)
{
    // Recalculate the dimensions of the lamp.
    auto newSize  = event->size();
    auto minWidth = (std::min(newSize.width(), newSize.height()) - 20) / 3;
    m_red->setMaximumSize(minWidth, minWidth);
    m_green->setMaximumSize(minWidth, minWidth);
    m_yellow->setMaximumSize(minWidth, minWidth);

    // Change the font size.
    QFont font;
    font.setPixelSize(minWidth * 0.5);
    m_red->setFont(font);
    m_green->setFont(font);
    m_yellow->setFont(font);

    QWidget::resizeEvent(event);
}

服务端示例

创建一个名称为 serverQt Console Application 程序。

控制中心并不需要显示任何数据,它负责计时以及更新信号灯的状态。

#include <QCoreApplication>
#include <QDebug>
#include <QJsonDocument>
#include <QTimer>
#include <QVariantMap>
#include <QVsoa>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // Create QVSOA server.
    QVsoaServer server("{\"name\":\"traffic_light\"}");
    if (server.isInvalid()) {
        qDebug() << "Can not create VSOA server!";
        return -1;
    }

    static int time = 0; // A variable used for timing
    QTimer timer;
    timer.setTimerType(Qt::PreciseTimer);
    // Every 1 second, update the status.
    QObject::connect(&timer, &QTimer::timeout, [&] {
        ++time;
        if (time >= 60) {
            time = 0;
        }
        QVariantMap msg;
        if (time < 30) {
            msg.insert("color", "red");
            msg.insert("countdown", 30 - time);
        } else if (time < 57) {
            msg.insert("color", "green");
            msg.insert("countdown", 57 - time);
        } else {
            msg.insert("color", "yellow");
            msg.insert("countdown", 60 - time);
        }
        server.publish("/light", QVsoaPayload(QJsonDocument::fromVariant(msg).toJson(), {}));
    });
    timer.start(1000);

    // Start the VSOA server
    if (!server.start(QVsoaSocketAddress(AF_INET, "0.0.0.0", 8888))) {
        qDebug() << "Can not start VSOA server!";
        return -1;
    }

    return a.exec();
}

运行效果

交通信号灯运行效果如下:

文档内容是否对您有所帮助?
有帮助
没帮助