开发使用指导
本节主要介绍 QVSOA 在 Qt 中的使用方法、帮助查看方法以及代码示例。
在 Qt 中使用 QVSOA
安装完 QVSOA 之后,即可在 Qt 工程中使用 QVSOA。下面分别介绍如何在 Qt 的 qmake 和 cmake 工程中使用 VSOA。
在 qmake 工程中使用
创建一个 Qt qmake 工程
app_qmake
。在工程文件
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
在源代码中添加头文件
#include <QVsoa>
。#include <QCoreApplication> #include <QVsoa> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); return a.exec(); }
在 cmake 工程中使用
创建一个 Qt cmake 工程
app_cmake
。在
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}")
在源代码中添加头文件
#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 客户端与服务端的开发示例。
客户端示例
创建一个名称为 client
的 Qt 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);
}
服务端示例
创建一个名称为 server
的 Qt 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();
}
运行效果
交通信号灯运行效果如下: