初步实现画点及下发逻辑。
This commit is contained in:
parent
e7e5c89807
commit
0f24d95eee
103
Application.cpp
103
Application.cpp
@ -4,17 +4,36 @@
|
|||||||
#include "DeviceConnection.h"
|
#include "DeviceConnection.h"
|
||||||
#include "H264Palyer.h"
|
#include "H264Palyer.h"
|
||||||
#include "VideoFrameProvider.h"
|
#include "VideoFrameProvider.h"
|
||||||
|
#include <QFont>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
|
|
||||||
Application::Application(int &argc, char **argv)
|
Application::Application(int &argc, char **argv)
|
||||||
: m_app(std::make_shared<QGuiApplication>(argc, argv)), m_videoFrameProvider(new VideoFrameProvider()),
|
: m_app(std::make_shared<QGuiApplication>(argc, argv)), m_videoFrameProvider(new VideoFrameProvider()),
|
||||||
m_player(std::make_shared<H264Palyer>()) {
|
m_player(std::make_shared<H264Palyer>()) {
|
||||||
|
QFont font;
|
||||||
|
font.setPointSize(16);
|
||||||
|
m_app->setFont(font);
|
||||||
m_app->setApplicationName(APPLICATION_NAME);
|
m_app->setApplicationName(APPLICATION_NAME);
|
||||||
m_app->setApplicationVersion(QString("v%1_%2 build: %3 %4").arg(APP_VERSION, GIT_COMMIT_ID, __DATE__, __TIME__));
|
m_app->setApplicationVersion(QString("v%1_%2 build: %3 %4").arg(APP_VERSION, GIT_COMMIT_ID, __DATE__, __TIME__));
|
||||||
m_player->open();
|
m_player->open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Application::currentOpenDoorAreaEnabled() const {
|
||||||
|
return m_currentOpenDoorAreaEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::setCurrentOpenDoorAreaEnabled(bool enabled) {
|
||||||
|
if (m_currentOpenDoorAreaEnabled != enabled) {
|
||||||
|
m_currentOpenDoorAreaEnabled = enabled;
|
||||||
|
emit currentOpenDoorAreaEnabledChanged();
|
||||||
|
if (m_device != nullptr) {
|
||||||
|
m_device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaEnabled, m_currentOpenDoorAreaPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG(info) << "setCurrentOpenDoorAreaEnabled " << enabled;
|
||||||
|
}
|
||||||
|
|
||||||
QList<QPointF> Application::currentOpenDoorAreaPoints() const {
|
QList<QPointF> Application::currentOpenDoorAreaPoints() const {
|
||||||
return m_currentOpenDoorAreaPoints;
|
return m_currentOpenDoorAreaPoints;
|
||||||
}
|
}
|
||||||
@ -26,11 +45,86 @@ void Application::setCurrentOpenDoorAreaPoints(const QList<QPointF> &points) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onDeviceOpenDoorAreaPoints(const QList<QPointF> &points) {
|
bool Application::currentShieldedAreaEnabled() const {
|
||||||
|
return m_currentShieldedAreaEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::setCurrentShieldedAreaEnabled(bool enabled) {
|
||||||
|
if (m_currentShieldedAreaEnabled != enabled) {
|
||||||
|
m_currentShieldedAreaEnabled = enabled;
|
||||||
|
emit currentShieldedAreaEnabledChanged();
|
||||||
|
if (m_device != nullptr) {
|
||||||
|
m_device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, m_currentShieldedAreaPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QPointF> Application::currentShieldedAreaPoints() const {
|
||||||
|
return m_currentShieldedAreaPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::setCurrentShieldedAreaPoints(const QList<QPointF> &points) {
|
||||||
|
if (m_currentShieldedAreaPoints != points) {
|
||||||
|
m_currentShieldedAreaPoints = points;
|
||||||
|
emit currentShieldedAreaPointsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Application::currentAntiClipAreaEnabled() const {
|
||||||
|
return m_currentAntiClipAreaEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::setCurrentAntiClipAreaEnabled(bool enabled) {
|
||||||
|
if (m_currentAntiClipAreaEnabled != enabled) {
|
||||||
|
m_currentAntiClipAreaEnabled = enabled;
|
||||||
|
emit currentAntiClipAreaEnabledChanged();
|
||||||
|
if (m_device != nullptr) {
|
||||||
|
m_device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, m_currentAntiClipAreaPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QPointF> Application::currentAntiClipAreaPoints() const {
|
||||||
|
return m_currentAntiClipAreaPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::setCurrentAntiClipAreaPoints(const QList<QPointF> &points) {
|
||||||
|
if (m_currentAntiClipAreaPoints != points) {
|
||||||
|
m_currentAntiClipAreaPoints = points;
|
||||||
|
emit currentAntiClipAreaPointsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateOpenDoorAreaPoints(const QList<QPointF> &points) {
|
||||||
|
LOG(info) << "updateOpenDoorAreaPoints: " << points.size();
|
||||||
|
m_device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaEnabled, points);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateAntiClipAreaPoints(const QList<QPointF> &points) {
|
||||||
|
m_device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, points);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::updateShieldedAreaPoints(const QList<QPointF> &points) {
|
||||||
|
m_device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, points);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onDeviceOpenDoorArea(bool enabled, const QList<QPointF> &points) {
|
||||||
|
setCurrentOpenDoorAreaEnabled(enabled);
|
||||||
setCurrentOpenDoorAreaPoints(points);
|
setCurrentOpenDoorAreaPoints(points);
|
||||||
LOG(info) << "onDeviceOpenDoorAreaPoints: " << points.size();
|
LOG(info) << "onDeviceOpenDoorAreaPoints: " << points.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::onDeviceShieldedArea(bool enabled, const QList<QPointF> &points) {
|
||||||
|
LOG(info) << "onDeviceShieldedArea: " << points.size();
|
||||||
|
setCurrentShieldedAreaEnabled(enabled);
|
||||||
|
setCurrentShieldedAreaPoints(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points) {
|
||||||
|
setCurrentAntiClipAreaEnabled(enabled);
|
||||||
|
setCurrentAntiClipAreaPoints(points);
|
||||||
|
}
|
||||||
|
|
||||||
int Application::exec() {
|
int Application::exec() {
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
engine.addImageProvider("videoframe", m_videoFrameProvider);
|
engine.addImageProvider("videoframe", m_videoFrameProvider);
|
||||||
@ -44,8 +138,9 @@ int Application::exec() {
|
|||||||
void Application::open() {
|
void Application::open() {
|
||||||
LOG(info) << "Application::start";
|
LOG(info) << "Application::start";
|
||||||
m_device = new DeviceConnection();
|
m_device = new DeviceConnection();
|
||||||
connect(m_device, &DeviceConnection::currentOpenDoorAreaPointsChanged, this,
|
connect(m_device, &DeviceConnection::currentOpenDoorAreaChanged, this, &Application::onDeviceOpenDoorArea);
|
||||||
&Application::onDeviceOpenDoorAreaPoints);
|
connect(m_device, &DeviceConnection::currentShieldedAreaChanged, this, &Application::onDeviceShieldedArea);
|
||||||
|
connect(m_device, &DeviceConnection::currentAntiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
|
||||||
m_device->connect();
|
m_device->connect();
|
||||||
m_device->setH264FrameCallback([this](const char *data, uint32_t size) {
|
m_device->setH264FrameCallback([this](const char *data, uint32_t size) {
|
||||||
auto image = m_player->decode((const uint8_t *)data, size);
|
auto image = m_player->decode((const uint8_t *)data, size);
|
||||||
@ -57,7 +152,9 @@ void Application::open() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Application::start() {
|
void Application::start() {
|
||||||
|
if (m_device != nullptr) {
|
||||||
m_device->start();
|
m_device->start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Application *Application::create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) {
|
Application *Application::create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) {
|
||||||
|
@ -15,13 +15,42 @@ class Application : public QObject {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
QML_NAMED_ELEMENT(App)
|
QML_NAMED_ELEMENT(App)
|
||||||
QML_SINGLETON
|
QML_SINGLETON
|
||||||
|
Q_PROPERTY(int DeviceWidth MEMBER DeviceWidth CONSTANT FINAL)
|
||||||
|
Q_PROPERTY(bool currentOpenDoorAreaEnabled READ currentOpenDoorAreaEnabled WRITE setCurrentOpenDoorAreaEnabled
|
||||||
|
NOTIFY currentOpenDoorAreaEnabledChanged)
|
||||||
Q_PROPERTY(QList<QPointF> currentOpenDoorAreaPoints READ currentOpenDoorAreaPoints WRITE
|
Q_PROPERTY(QList<QPointF> currentOpenDoorAreaPoints READ currentOpenDoorAreaPoints WRITE
|
||||||
setCurrentOpenDoorAreaPoints NOTIFY currentOpenDoorAreaPointsChanged)
|
setCurrentOpenDoorAreaPoints NOTIFY currentOpenDoorAreaPointsChanged)
|
||||||
|
Q_PROPERTY(bool currentShieldedAreaEnabled READ currentShieldedAreaEnabled WRITE setCurrentShieldedAreaEnabled
|
||||||
|
NOTIFY currentShieldedAreaEnabledChanged)
|
||||||
|
Q_PROPERTY(QList<QPointF> currentShieldedAreaPoints READ currentShieldedAreaPoints WRITE
|
||||||
|
setCurrentShieldedAreaPoints NOTIFY currentShieldedAreaPointsChanged)
|
||||||
|
Q_PROPERTY(bool currentAntiClipAreaEnabled READ currentAntiClipAreaEnabled WRITE setCurrentAntiClipAreaEnabled
|
||||||
|
NOTIFY currentAntiClipAreaEnabledChanged)
|
||||||
|
Q_PROPERTY(QList<QPointF> currentAntiClipAreaPoints READ currentAntiClipAreaPoints WRITE
|
||||||
|
setCurrentAntiClipAreaPoints NOTIFY currentAntiClipAreaPointsChanged)
|
||||||
friend class Amass::Singleton<Application>;
|
friend class Amass::Singleton<Application>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
constexpr static int DeviceWidth = 640;
|
||||||
|
bool currentOpenDoorAreaEnabled() const;
|
||||||
|
void setCurrentOpenDoorAreaEnabled(bool enabled);
|
||||||
QList<QPointF> currentOpenDoorAreaPoints() const;
|
QList<QPointF> currentOpenDoorAreaPoints() const;
|
||||||
void setCurrentOpenDoorAreaPoints(const QList<QPointF> &points);
|
void setCurrentOpenDoorAreaPoints(const QList<QPointF> &points);
|
||||||
|
|
||||||
|
bool currentShieldedAreaEnabled() const;
|
||||||
|
void setCurrentShieldedAreaEnabled(bool enabled);
|
||||||
|
QList<QPointF> currentShieldedAreaPoints() const;
|
||||||
|
void setCurrentShieldedAreaPoints(const QList<QPointF> &points);
|
||||||
|
|
||||||
|
bool currentAntiClipAreaEnabled() const;
|
||||||
|
void setCurrentAntiClipAreaEnabled(bool enabled);
|
||||||
|
QList<QPointF> currentAntiClipAreaPoints() const;
|
||||||
|
void setCurrentAntiClipAreaPoints(const QList<QPointF> &points);
|
||||||
|
|
||||||
|
Q_INVOKABLE void updateOpenDoorAreaPoints(const QList<QPointF> &points);
|
||||||
|
Q_INVOKABLE void updateAntiClipAreaPoints(const QList<QPointF> &points);
|
||||||
|
Q_INVOKABLE void updateShieldedAreaPoints(const QList<QPointF> &points);
|
||||||
|
|
||||||
int exec();
|
int exec();
|
||||||
Q_INVOKABLE void open();
|
Q_INVOKABLE void open();
|
||||||
Q_INVOKABLE void start();
|
Q_INVOKABLE void start();
|
||||||
@ -30,10 +59,17 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void newVideoFrame();
|
void newVideoFrame();
|
||||||
void currentOpenDoorAreaPointsChanged();
|
void currentOpenDoorAreaPointsChanged();
|
||||||
|
void currentShieldedAreaPointsChanged();
|
||||||
|
void currentAntiClipAreaPointsChanged();
|
||||||
|
void currentOpenDoorAreaEnabledChanged();
|
||||||
|
void currentShieldedAreaEnabledChanged();
|
||||||
|
void currentAntiClipAreaEnabledChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Application(int &argc, char **argv);
|
Application(int &argc, char **argv);
|
||||||
void onDeviceOpenDoorAreaPoints(const QList<QPointF> &points);
|
void onDeviceOpenDoorArea(bool enabled, const QList<QPointF> &points);
|
||||||
|
void onDeviceShieldedArea(bool enabled, const QList<QPointF> &points);
|
||||||
|
void onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<QGuiApplication> m_app;
|
std::shared_ptr<QGuiApplication> m_app;
|
||||||
@ -41,7 +77,12 @@ private:
|
|||||||
std::shared_ptr<H264Palyer> m_player;
|
std::shared_ptr<H264Palyer> m_player;
|
||||||
DeviceConnection *m_device = nullptr;
|
DeviceConnection *m_device = nullptr;
|
||||||
|
|
||||||
|
bool m_currentOpenDoorAreaEnabled = false;
|
||||||
QList<QPointF> m_currentOpenDoorAreaPoints;
|
QList<QPointF> m_currentOpenDoorAreaPoints;
|
||||||
|
bool m_currentShieldedAreaEnabled = false;
|
||||||
|
QList<QPointF> m_currentShieldedAreaPoints;
|
||||||
|
bool m_currentAntiClipAreaEnabled = false;
|
||||||
|
QList<QPointF> m_currentAntiClipAreaPoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // APPLICATION_H
|
#endif // APPLICATION_H
|
||||||
|
@ -37,6 +37,7 @@ void DeviceConnection::start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DeviceConnection::requestOpenDoorArea() {
|
void DeviceConnection::requestOpenDoorArea() {
|
||||||
|
auto task = [this]() {
|
||||||
boost::json::object request;
|
boost::json::object request;
|
||||||
request["func"] = "a03opendoor1_getdata";
|
request["func"] = "a03opendoor1_getdata";
|
||||||
request["deviceid"] = "0";
|
request["deviceid"] = "0";
|
||||||
@ -45,14 +46,158 @@ void DeviceConnection::requestOpenDoorArea() {
|
|||||||
auto text = boost::json::serialize(request);
|
auto text = boost::json::serialize(request);
|
||||||
m_commandSocket->write(text.data(), text.size());
|
m_commandSocket->write(text.data(), text.size());
|
||||||
LOG(info) << "requestOpenDoorArea";
|
LOG(info) << "requestOpenDoorArea";
|
||||||
|
};
|
||||||
|
if (m_requests.empty()) {
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
m_requests.push(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceConnection::updateOpenDoorAreaPoints(bool enabled, const QList<QPointF> &points) {
|
||||||
|
auto task = [this, enabled, points]() {
|
||||||
|
boost::json::object request;
|
||||||
|
request["func"] = "a03opendoor1_setdata";
|
||||||
|
request["deviceid"] = "0";
|
||||||
|
boost::json::object data;
|
||||||
|
data["value"] = enabled ? "1" : "0";
|
||||||
|
boost::json::array pointArray;
|
||||||
|
for (auto &p : points) {
|
||||||
|
boost::json::object point;
|
||||||
|
point["x"] = p.x();
|
||||||
|
point["y"] = p.y();
|
||||||
|
pointArray.push_back(std::move(point));
|
||||||
|
}
|
||||||
|
data["points"] = std::move(pointArray);
|
||||||
|
request["data"] = std::move(data);
|
||||||
|
|
||||||
|
auto text = boost::json::serialize(request);
|
||||||
|
m_commandSocket->write(text.data(), text.size());
|
||||||
|
LOG(info) << "updateOpenDoorAreaPoints";
|
||||||
|
};
|
||||||
|
if (m_requests.empty()) {
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
m_requests.push(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceConnection::requestShieldedArea() {
|
||||||
|
auto task = [this]() {
|
||||||
|
boost::json::object request;
|
||||||
|
request["func"] = "a03opendoor4_getdata";
|
||||||
|
request["deviceid"] = "0";
|
||||||
|
boost::json::object data;
|
||||||
|
request["data"] = std::move(data);
|
||||||
|
auto text = boost::json::serialize(request);
|
||||||
|
m_commandSocket->write(text.data(), text.size());
|
||||||
|
LOG(info) << "requestShieldedArea";
|
||||||
|
};
|
||||||
|
if (m_requests.empty()) {
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
m_requests.push(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceConnection::updateShieldedAreaPoints(bool enabled, const QList<QPointF> &points) {
|
||||||
|
auto task = [this, enabled, points]() {
|
||||||
|
boost::json::object request;
|
||||||
|
request["func"] = "a03opendoor4_setdata";
|
||||||
|
request["deviceid"] = "0";
|
||||||
|
boost::json::object data;
|
||||||
|
data["value"] = enabled ? "1" : "0";
|
||||||
|
boost::json::array pointArray;
|
||||||
|
for (auto &p : points) {
|
||||||
|
boost::json::object point;
|
||||||
|
point["x"] = p.x();
|
||||||
|
point["y"] = p.y();
|
||||||
|
pointArray.push_back(std::move(point));
|
||||||
|
}
|
||||||
|
data["points"] = std::move(pointArray);
|
||||||
|
request["data"] = std::move(data);
|
||||||
|
|
||||||
|
auto text = boost::json::serialize(request);
|
||||||
|
m_commandSocket->write(text.data(), text.size());
|
||||||
|
LOG(info) << "updateShieldedAreaPoints";
|
||||||
|
};
|
||||||
|
if (m_requests.empty()) {
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
m_requests.push(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceConnection::requestAntiClipArea() {
|
||||||
|
auto task = [this]() {
|
||||||
|
boost::json::object request;
|
||||||
|
request["func"] = "a03opendoor5_getdata";
|
||||||
|
request["deviceid"] = "0";
|
||||||
|
boost::json::object data;
|
||||||
|
request["data"] = std::move(data);
|
||||||
|
auto text = boost::json::serialize(request);
|
||||||
|
m_commandSocket->write(text.data(), text.size());
|
||||||
|
LOG(info) << "requestAntiClipArea";
|
||||||
|
};
|
||||||
|
if (m_requests.empty()) {
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
m_requests.push(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceConnection::updateAntiClipAreaPoints(bool enabled, const QList<QPointF> &points) {
|
||||||
|
auto task = [this, enabled, points]() {
|
||||||
|
boost::json::object request;
|
||||||
|
request["func"] = "a03opendoor5_setdata";
|
||||||
|
request["deviceid"] = "0";
|
||||||
|
boost::json::object data;
|
||||||
|
data["value"] = enabled ? "1" : "0";
|
||||||
|
boost::json::array pointArray;
|
||||||
|
for (auto &p : points) {
|
||||||
|
boost::json::object point;
|
||||||
|
point["x"] = p.x();
|
||||||
|
point["y"] = p.y();
|
||||||
|
pointArray.push_back(std::move(point));
|
||||||
|
}
|
||||||
|
data["points"] = std::move(pointArray);
|
||||||
|
request["data"] = std::move(data);
|
||||||
|
|
||||||
|
auto text = boost::json::serialize(request);
|
||||||
|
m_commandSocket->write(text.data(), text.size());
|
||||||
|
LOG(info) << "updateAntiClipAreaPoints";
|
||||||
|
};
|
||||||
|
if (m_requests.empty()) {
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
m_requests.push(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceConnection::requestResolution(Resolution resolution) {
|
||||||
|
auto task = [this, resolution]() {
|
||||||
|
boost::json::object request;
|
||||||
|
request["func"] = "quality_setdata";
|
||||||
|
request["deviceid"] = "0";
|
||||||
|
boost::json::object data;
|
||||||
|
data["value"] = static_cast<int>(resolution);
|
||||||
|
request["data"] = std::move(data);
|
||||||
|
auto text = boost::json::serialize(request);
|
||||||
|
m_commandSocket->write(text.data(), text.size());
|
||||||
|
LOG(info) << "requestShieldedArea";
|
||||||
|
};
|
||||||
|
if (m_requests.empty()) {
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
m_requests.push(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceConnection::handleCommand(const std::string_view &replyText) {
|
void DeviceConnection::handleCommand(const std::string_view &replyText) {
|
||||||
auto replyValue = boost::json::parse(replyText);
|
boost::system::error_code error;
|
||||||
|
auto replyValue = boost::json::parse(replyText, error);
|
||||||
|
if (error) {
|
||||||
|
LOG(error) << "prase [" << replyText << "] failed, message: " << error.message();
|
||||||
|
return;
|
||||||
|
}
|
||||||
auto &reply = replyValue.as_object();
|
auto &reply = replyValue.as_object();
|
||||||
auto &function = reply.at("func").as_string();
|
auto &function = reply.at("func").as_string();
|
||||||
if (function == "a03opendoor1_getdata") {
|
if (function == "a03opendoor1_getdata") {
|
||||||
auto &data = reply.at("data").as_object();
|
auto &data = reply.at("data").as_object();
|
||||||
|
auto &value = data.at("value").as_string();
|
||||||
auto &pointArray = data.at("points").as_array();
|
auto &pointArray = data.at("points").as_array();
|
||||||
QList<QPointF> points;
|
QList<QPointF> points;
|
||||||
for (auto &p : pointArray) {
|
for (auto &p : pointArray) {
|
||||||
@ -62,7 +207,33 @@ void DeviceConnection::handleCommand(const std::string_view &replyText) {
|
|||||||
point.setY(obj.at("y").as_double());
|
point.setY(obj.at("y").as_double());
|
||||||
points.push_back(point);
|
points.push_back(point);
|
||||||
}
|
}
|
||||||
emit currentOpenDoorAreaPointsChanged(points);
|
emit currentOpenDoorAreaChanged(value == "1", points);
|
||||||
|
} else if (function == "a03opendoor4_getdata") {
|
||||||
|
auto &data = reply.at("data").as_object();
|
||||||
|
auto &value = data.at("value").as_string();
|
||||||
|
auto &pointArray = data.at("points").as_array();
|
||||||
|
QList<QPointF> points;
|
||||||
|
for (auto &p : pointArray) {
|
||||||
|
QPointF point;
|
||||||
|
auto &obj = p.as_object();
|
||||||
|
point.setX(obj.at("x").as_double());
|
||||||
|
point.setY(obj.at("y").as_double());
|
||||||
|
points.push_back(point);
|
||||||
|
}
|
||||||
|
emit currentShieldedAreaChanged(value == "1", points);
|
||||||
|
} else if (function == "a03opendoor5_getdata") {
|
||||||
|
auto &data = reply.at("data").as_object();
|
||||||
|
auto &value = data.at("value").as_string();
|
||||||
|
auto &pointArray = data.at("points").as_array();
|
||||||
|
QList<QPointF> points;
|
||||||
|
for (auto &p : pointArray) {
|
||||||
|
QPointF point;
|
||||||
|
auto &obj = p.as_object();
|
||||||
|
point.setX(obj.at("x").as_double());
|
||||||
|
point.setY(obj.at("y").as_double());
|
||||||
|
points.push_back(point);
|
||||||
|
}
|
||||||
|
emit currentAntiClipAreaChanged(value == "1", points);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +242,8 @@ void DeviceConnection::onConnected() {
|
|||||||
auto socket = dynamic_cast<QTcpSocket *>(sender());
|
auto socket = dynamic_cast<QTcpSocket *>(sender());
|
||||||
if (socket == m_commandSocket) {
|
if (socket == m_commandSocket) {
|
||||||
requestOpenDoorArea();
|
requestOpenDoorArea();
|
||||||
|
requestShieldedArea();
|
||||||
|
requestAntiClipArea();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,5 +282,9 @@ void DeviceConnection::onCommandReadyRead() {
|
|||||||
LOG(info) << "h264 reply: " << m_commandBuffer.data() + sizeof(uint32_t);
|
LOG(info) << "h264 reply: " << m_commandBuffer.data() + sizeof(uint32_t);
|
||||||
handleCommand(std::string_view(m_commandBuffer.data() + sizeof(uint32_t), packageSize));
|
handleCommand(std::string_view(m_commandBuffer.data() + sizeof(uint32_t), packageSize));
|
||||||
m_commandBuffer.remove(0, packageSize + sizeof(uint32_t));
|
m_commandBuffer.remove(0, packageSize + sizeof(uint32_t));
|
||||||
|
m_requests.pop();
|
||||||
|
if (!m_requests.empty()) {
|
||||||
|
m_requests.front()();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,22 +2,44 @@
|
|||||||
#define DEVICECONNECTION_H
|
#define DEVICECONNECTION_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <queue>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
class QTcpSocket;
|
class QTcpSocket;
|
||||||
|
|
||||||
class DeviceConnection : public QObject {
|
class DeviceConnection : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
QML_ELEMENT
|
||||||
|
QML_UNCREATABLE("Only used in C++...")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum Resolution {
|
||||||
|
Video_360P = 0,
|
||||||
|
Video_720P,
|
||||||
|
};
|
||||||
|
enum AreaWay {
|
||||||
|
Diabled = 0,
|
||||||
|
FullScreen,
|
||||||
|
Quadrangle, // 四边形
|
||||||
|
};
|
||||||
|
Q_ENUM(AreaWay)
|
||||||
using H264FrameCallback = std::function<void(const char *data, uint32_t size)>;
|
using H264FrameCallback = std::function<void(const char *data, uint32_t size)>;
|
||||||
explicit DeviceConnection(QObject *parent = nullptr);
|
explicit DeviceConnection(QObject *parent = nullptr);
|
||||||
void setH264FrameCallback(H264FrameCallback &&callback);
|
void setH264FrameCallback(H264FrameCallback &&callback);
|
||||||
void connect();
|
void connect();
|
||||||
void start();
|
void start();
|
||||||
void requestOpenDoorArea();
|
void requestOpenDoorArea();
|
||||||
|
void updateOpenDoorAreaPoints(bool enabled, const QList<QPointF> &points);
|
||||||
|
void requestShieldedArea();
|
||||||
|
void updateShieldedAreaPoints(bool enabled, const QList<QPointF> &points);
|
||||||
|
void requestAntiClipArea();
|
||||||
|
void updateAntiClipAreaPoints(bool enabled, const QList<QPointF> &points);
|
||||||
|
void requestResolution(Resolution resolution);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void currentOpenDoorAreaPointsChanged(const QList<QPointF> &points);
|
void currentOpenDoorAreaChanged(bool enabled, const QList<QPointF> &points);
|
||||||
|
void currentShieldedAreaChanged(bool enabled, const QList<QPointF> &points);
|
||||||
|
void currentAntiClipAreaChanged(bool enabled, const QList<QPointF> &points);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onConnected();
|
void onConnected();
|
||||||
@ -34,6 +56,7 @@ private:
|
|||||||
QByteArray m_commandBuffer;
|
QByteArray m_commandBuffer;
|
||||||
QByteArray m_h264Buffer;
|
QByteArray m_h264Buffer;
|
||||||
H264FrameCallback m_frameCallback;
|
H264FrameCallback m_frameCallback;
|
||||||
|
std::queue<std::function<void()>> m_requests;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEVICECONNECTION_H
|
#endif // DEVICECONNECTION_H
|
||||||
|
205
DeviceView.qml
205
DeviceView.qml
@ -1,10 +1,25 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
import AntiClipSettings
|
import AntiClipSettings
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
property int dargWidth: 10
|
property int dargWidth: 12
|
||||||
|
property color openDoorAreaColor: "green"
|
||||||
property var openDoorAreaPoints: []
|
property var openDoorAreaPoints: []
|
||||||
|
property bool openDoorAreaEnabled: false
|
||||||
|
property var shieldedAreaPoints: []
|
||||||
|
property bool shieldedAreaEnabled: false
|
||||||
|
property color antiClipAreaColor: "blue"
|
||||||
|
property var antiClipAreaPoints: []
|
||||||
|
property bool antiClipAreaEnabled: false
|
||||||
|
property var defaultShieldedAreaPoints: [Qt.point(6, 6), Qt.point(40, 60),
|
||||||
|
Qt.point(598, 6), Qt.point(633, 60)]
|
||||||
|
Item {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: controlBar.top
|
||||||
Image {
|
Image {
|
||||||
id: image
|
id: image
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@ -12,7 +27,7 @@ Item {
|
|||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: "image://videoframe/"
|
source: "image://videoframe/"
|
||||||
property real aspectRatio: 16 / 9
|
property real aspectRatio: 16 / 9
|
||||||
width: Math.min(root.width, root.height * aspectRatio)
|
width: Math.min(parent.width, parent.height * aspectRatio)
|
||||||
height: width / aspectRatio
|
height: width / aspectRatio
|
||||||
|
|
||||||
Canvas {
|
Canvas {
|
||||||
@ -21,8 +36,8 @@ Item {
|
|||||||
onPaint: {
|
onPaint: {
|
||||||
var ctx = canvas.getContext("2d")
|
var ctx = canvas.getContext("2d")
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
if (openDoorAreaPoints.length > 0) {
|
if (openDoorAreaEnabled &&(openDoorAreaPoints.length > 0)) {
|
||||||
ctx.strokeStyle = "red"
|
ctx.strokeStyle = openDoorAreaColor
|
||||||
ctx.lineWidth = 2
|
ctx.lineWidth = 2
|
||||||
|
|
||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
@ -37,16 +52,81 @@ Item {
|
|||||||
ctx.closePath()
|
ctx.closePath()
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
}
|
}
|
||||||
|
if (antiClipAreaEnabled && (antiClipAreaPoints.length > 0)) {
|
||||||
|
ctx.strokeStyle = antiClipAreaColor
|
||||||
|
ctx.lineWidth = 2
|
||||||
|
|
||||||
|
ctx.beginPath()
|
||||||
|
let point = scaledPoint(antiClipAreaPoints[0],
|
||||||
|
width, height)
|
||||||
|
ctx.moveTo(point.x, point.y)
|
||||||
|
for (var i = 1; i < antiClipAreaPoints.length; i++) {
|
||||||
|
point = scaledPoint(antiClipAreaPoints[i],
|
||||||
|
width, height)
|
||||||
|
ctx.lineTo(point.x, point.y)
|
||||||
|
}
|
||||||
|
ctx.closePath()
|
||||||
|
ctx.stroke()
|
||||||
|
}
|
||||||
|
if (shieldedAreaEnabled &&(shieldedAreaPoints.length > 0)) {
|
||||||
|
ctx.strokeStyle = "green"
|
||||||
|
let point0 = scaledPoint(shieldedAreaPoints[0],
|
||||||
|
width, height)
|
||||||
|
let point1 = scaledPoint(shieldedAreaPoints[1],
|
||||||
|
width, height)
|
||||||
|
let point2 = scaledPoint(shieldedAreaPoints[2],
|
||||||
|
width, height)
|
||||||
|
let point3 = scaledPoint(shieldedAreaPoints[3],
|
||||||
|
width, height)
|
||||||
|
ctx.strokeRect(point0.x, point0.y, point1.x - point0.x,
|
||||||
|
point1.y - point0.y)
|
||||||
|
ctx.strokeRect(point2.x, point2.y, point3.x - point2.x,
|
||||||
|
point3.y - point2.y)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
|
visible: openDoorAreaEnabled
|
||||||
model: openDoorAreaPoints
|
model: openDoorAreaPoints
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
width: dargWidth
|
width: dargWidth
|
||||||
height: dargWidth
|
height: dargWidth
|
||||||
color: "red"
|
visible: openDoorAreaEnabled
|
||||||
|
color: openDoorAreaColor
|
||||||
|
x: scaledPoint(modelData, canvas.width,
|
||||||
|
canvas.height).x - width / 2
|
||||||
|
y: scaledPoint(modelData, canvas.width,
|
||||||
|
canvas.height).y - height / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: shieldedAreaRepeater
|
||||||
|
model: shieldedAreaPoints
|
||||||
|
visible: shieldedAreaEnabled
|
||||||
|
delegate: Rectangle {
|
||||||
|
width: dargWidth
|
||||||
|
height: dargWidth
|
||||||
|
visible: shieldedAreaEnabled
|
||||||
|
color: "green"
|
||||||
|
x: scaledPoint(modelData, canvas.width,
|
||||||
|
canvas.height).x - width / 2
|
||||||
|
y: scaledPoint(modelData, canvas.width,
|
||||||
|
canvas.height).y - height / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: antiAreaRepeater
|
||||||
|
visible: antiClipAreaEnabled
|
||||||
|
model: antiClipAreaPoints
|
||||||
|
delegate: Rectangle {
|
||||||
|
visible: antiClipAreaEnabled
|
||||||
|
width: dargWidth
|
||||||
|
height: dargWidth
|
||||||
|
color: antiClipAreaColor
|
||||||
x: scaledPoint(modelData, canvas.width,
|
x: scaledPoint(modelData, canvas.width,
|
||||||
canvas.height).x - width / 2
|
canvas.height).x - width / 2
|
||||||
y: scaledPoint(modelData, canvas.width,
|
y: scaledPoint(modelData, canvas.width,
|
||||||
@ -56,28 +136,85 @@ Item {
|
|||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
property int draggedPointIndex: -1
|
property int draggedOpenDoorAreaPointIndex: -1
|
||||||
|
property int draggedShieldedAreaPointIndex: -1
|
||||||
|
property int draggedAntiAreaPointIndex: -1
|
||||||
onPressed: mouse => {
|
onPressed: mouse => {
|
||||||
|
if(openDoorAreaEnabled){
|
||||||
for (var i = 0; i < openDoorAreaPoints.length; i++) {
|
for (var i = 0; i < openDoorAreaPoints.length; i++) {
|
||||||
let point = scaledPoint(openDoorAreaPoints[i],
|
let point = scaledPoint(
|
||||||
canvas.width,
|
openDoorAreaPoints[i], canvas.width,
|
||||||
canvas.height)
|
canvas.height)
|
||||||
if (isInside(mouse.x, mouse.y, point)) {
|
if (isInside(mouse.x, mouse.y, point)) {
|
||||||
draggedPointIndex = i
|
draggedOpenDoorAreaPointIndex = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (draggedOpenDoorAreaPointIndex >= 0)
|
||||||
|
return
|
||||||
|
if(shieldedAreaEnabled){
|
||||||
|
for (let i = 0; i < shieldedAreaPoints.length; i++) {
|
||||||
|
let point = scaledPoint(
|
||||||
|
shieldedAreaPoints[i], canvas.width,
|
||||||
|
canvas.height)
|
||||||
|
if (isInside(mouse.x, mouse.y, point)) {
|
||||||
|
draggedShieldedAreaPointIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (draggedShieldedAreaPointIndex >= 0)
|
||||||
|
return
|
||||||
|
if(antiClipAreaEnabled){
|
||||||
|
for (let i = 0; i < antiClipAreaPoints.length; i++) {
|
||||||
|
let point = scaledPoint(
|
||||||
|
antiClipAreaPoints[i], canvas.width,
|
||||||
|
canvas.height)
|
||||||
|
if (isInside(mouse.x, mouse.y, point)) {
|
||||||
|
draggedAntiAreaPointIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
onReleased: {
|
onReleased: {
|
||||||
draggedPointIndex = -1
|
if (draggedOpenDoorAreaPointIndex >= 0) {
|
||||||
|
App.updateOpenDoorAreaPoints(openDoorAreaPoints)
|
||||||
|
draggedOpenDoorAreaPointIndex = -1
|
||||||
|
}
|
||||||
|
if (draggedShieldedAreaPointIndex >= 0) {
|
||||||
|
App.updateShieldedAreaPoints(shieldedAreaPoints)
|
||||||
|
draggedShieldedAreaPointIndex = -1
|
||||||
|
}
|
||||||
|
if (draggedAntiAreaPointIndex >= 0) {
|
||||||
|
App.updateAntiClipAreaPoints(antiClipAreaPoints)
|
||||||
|
draggedAntiAreaPointIndex = -1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onPositionChanged: mouse => {
|
onPositionChanged: mouse => {
|
||||||
if (draggedPointIndex >= 0) {
|
if ((mouse.x < 0) || (mouse.x > canvas.width) || (mouse.y < 0) || (mouse.y > canvas.height)) return
|
||||||
openDoorAreaPoints[draggedPointIndex] = standardPoint(
|
if (draggedOpenDoorAreaPointIndex >= 0) {
|
||||||
Qt.point(mouse.x, mouse.y),
|
openDoorAreaPoints[draggedOpenDoorAreaPointIndex]
|
||||||
canvas.width, canvas.height)
|
= standardPoint(Qt.point(mouse.x, mouse.y), canvas.width, canvas.height)
|
||||||
canvas.requestPaint()
|
canvas.requestPaint()
|
||||||
repeater.model = openDoorAreaPoints
|
repeater.model = openDoorAreaPoints
|
||||||
|
} else if (draggedShieldedAreaPointIndex >= 0) {
|
||||||
|
shieldedAreaPoints[draggedShieldedAreaPointIndex]
|
||||||
|
= standardPoint(Qt.point(mouse.x,
|
||||||
|
mouse.y),
|
||||||
|
canvas.width,
|
||||||
|
canvas.height)
|
||||||
|
canvas.requestPaint()
|
||||||
|
shieldedAreaRepeater.model = shieldedAreaPoints
|
||||||
|
} else if (draggedAntiAreaPointIndex >= 0) {
|
||||||
|
antiClipAreaPoints[draggedAntiAreaPointIndex]
|
||||||
|
= standardPoint(Qt.point(mouse.x,
|
||||||
|
mouse.y),
|
||||||
|
canvas.width,
|
||||||
|
canvas.height)
|
||||||
|
canvas.requestPaint()
|
||||||
|
antiAreaRepeater.model = antiClipAreaPoints
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +225,28 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
id: controlBar
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
Switch {
|
||||||
|
text: "开门区域"
|
||||||
|
checked: openDoorAreaEnabled
|
||||||
|
onToggled: App.currentOpenDoorAreaEnabled = checked
|
||||||
|
}
|
||||||
|
Switch {
|
||||||
|
text: "防夹区域"
|
||||||
|
checked: antiClipAreaEnabled
|
||||||
|
onToggled: App.currentAntiClipAreaEnabled = checked
|
||||||
|
}
|
||||||
|
Switch {
|
||||||
|
text: "屏蔽区域"
|
||||||
|
checked: shieldedAreaEnabled
|
||||||
|
onToggled: App.currentShieldedAreaEnabled = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
// 转换为显示画点
|
// 转换为显示画点
|
||||||
function scaledPoint(point, width, height) {
|
function scaledPoint(point, width, height) {
|
||||||
let x = point.x * width / 640
|
let x = point.x * width / 640
|
||||||
@ -96,8 +254,8 @@ Item {
|
|||||||
return Qt.point(x, y)
|
return Qt.point(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
function standardPoint(point, width, height) {
|
|
||||||
// 转换为设备画点(640x360)
|
// 转换为设备画点(640x360)
|
||||||
|
function standardPoint(point, width, height) {
|
||||||
let x = point.x * 640 / width
|
let x = point.x * 640 / width
|
||||||
let y = point.y * 360 / height
|
let y = point.y * 360 / height
|
||||||
return Qt.point(x, y)
|
return Qt.point(x, y)
|
||||||
@ -112,5 +270,20 @@ Item {
|
|||||||
function onCurrentOpenDoorAreaPointsChanged() {
|
function onCurrentOpenDoorAreaPointsChanged() {
|
||||||
canvas.requestPaint()
|
canvas.requestPaint()
|
||||||
}
|
}
|
||||||
|
function onCurrentShieldedAreaPointsChanged() {
|
||||||
|
canvas.requestPaint()
|
||||||
|
}
|
||||||
|
function onCurrentAntiClipAreaPointsChanged() {
|
||||||
|
canvas.requestPaint()
|
||||||
|
}
|
||||||
|
function onCurrentOpenDoorAreaEnabledChanged(){
|
||||||
|
canvas.requestPaint()
|
||||||
|
}
|
||||||
|
function onCurrentShieldedAreaEnabledChanged(){
|
||||||
|
canvas.requestPaint()
|
||||||
|
}
|
||||||
|
function onCurrentAntiClipAreaEnabledChanged(){
|
||||||
|
canvas.requestPaint()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
Main.qml
35
Main.qml
@ -1,23 +1,33 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
import AntiClipSettings
|
import AntiClipSettings
|
||||||
|
|
||||||
ApplicationWindow {
|
ApplicationWindow {
|
||||||
width: 640
|
width: 680
|
||||||
height: 480
|
height: 480
|
||||||
visible: true
|
visible: true
|
||||||
title: qsTr("Hello World")
|
title: qsTr("Hello World")
|
||||||
|
|
||||||
header: Row {
|
header: ToolBar {
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
Button {
|
||||||
|
text: "搜索设备"
|
||||||
|
}
|
||||||
Button {
|
Button {
|
||||||
text: "连接"
|
text: "连接"
|
||||||
onClicked: App.open()
|
onClicked: App.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
text: "开始"
|
text: "开始"
|
||||||
onClicked: App.start()
|
onClicked: App.start()
|
||||||
}
|
}
|
||||||
|
Text {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: qsTr("当前设备版本号: RD_T009_V02R001B001")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@ -34,6 +44,25 @@ ApplicationWindow {
|
|||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: deviceList.right
|
anchors.left: deviceList.right
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
openDoorAreaEnabled: App.currentOpenDoorAreaEnabled
|
||||||
openDoorAreaPoints: App.currentOpenDoorAreaPoints
|
openDoorAreaPoints: App.currentOpenDoorAreaPoints
|
||||||
|
shieldedAreaEnabled: App.currentShieldedAreaEnabled
|
||||||
|
shieldedAreaPoints: App.currentShieldedAreaPoints
|
||||||
|
antiClipAreaEnabled: App.currentAntiClipAreaEnabled
|
||||||
|
antiClipAreaPoints: App.currentAntiClipAreaPoints
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: RowLayout {
|
||||||
|
width: parent.width
|
||||||
|
Item {}
|
||||||
|
Button {
|
||||||
|
text: "数据采集"
|
||||||
|
}
|
||||||
|
Item {}
|
||||||
|
Button {
|
||||||
|
text: "升级"
|
||||||
|
}
|
||||||
|
Item {}
|
||||||
|
spacing: (parent.width - (2 * 100)) / 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user