初步实现画点及下发逻辑。

This commit is contained in:
luocai 2024-08-14 20:01:38 +08:00
parent e7e5c89807
commit 0f24d95eee
6 changed files with 644 additions and 104 deletions

View File

@ -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() {
m_device->start(); if (m_device != nullptr) {
m_device->start();
}
} }
Application *Application::create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) { Application *Application::create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) {

View File

@ -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

View File

@ -37,22 +37,167 @@ void DeviceConnection::start() {
} }
void DeviceConnection::requestOpenDoorArea() { void DeviceConnection::requestOpenDoorArea() {
boost::json::object request; auto task = [this]() {
request["func"] = "a03opendoor1_getdata"; boost::json::object request;
request["deviceid"] = "0"; request["func"] = "a03opendoor1_getdata";
boost::json::object data; request["deviceid"] = "0";
request["data"] = std::move(data); boost::json::object data;
auto text = boost::json::serialize(request); request["data"] = std::move(data);
m_commandSocket->write(text.data(), text.size()); auto text = boost::json::serialize(request);
LOG(info) << "requestOpenDoorArea"; m_commandSocket->write(text.data(), text.size());
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()();
}
} }
} }

View File

@ -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

View File

@ -1,94 +1,252 @@
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: []
Image { property bool openDoorAreaEnabled: false
id: image property var shieldedAreaPoints: []
anchors.centerIn: parent property bool shieldedAreaEnabled: false
cache: false property color antiClipAreaColor: "blue"
fillMode: Image.PreserveAspectFit property var antiClipAreaPoints: []
source: "image://videoframe/" property bool antiClipAreaEnabled: false
property real aspectRatio: 16 / 9 property var defaultShieldedAreaPoints: [Qt.point(6, 6), Qt.point(40, 60),
width: Math.min(root.width, root.height * aspectRatio) Qt.point(598, 6), Qt.point(633, 60)]
height: width / aspectRatio Item {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: controlBar.top
Image {
id: image
anchors.centerIn: parent
cache: false
fillMode: Image.PreserveAspectFit
source: "image://videoframe/"
property real aspectRatio: 16 / 9
width: Math.min(parent.width, parent.height * aspectRatio)
height: width / aspectRatio
Canvas { Canvas {
id: canvas id: canvas
anchors.fill: parent anchors.fill: parent
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()
let point = scaledPoint(openDoorAreaPoints[0], let point = scaledPoint(openDoorAreaPoints[0],
width, height) width, height)
ctx.moveTo(point.x, point.y) ctx.moveTo(point.x, point.y)
for (var i = 1; i < openDoorAreaPoints.length; i++) { for (var i = 1; i < openDoorAreaPoints.length; i++) {
point = scaledPoint(openDoorAreaPoints[i], point = scaledPoint(openDoorAreaPoints[i],
width, height) width, height)
ctx.lineTo(point.x, point.y) ctx.lineTo(point.x, point.y)
}
ctx.closePath()
ctx.stroke()
} }
ctx.closePath() if (antiClipAreaEnabled && (antiClipAreaPoints.length > 0)) {
ctx.stroke() 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 {
id: repeater
visible: openDoorAreaEnabled
model: openDoorAreaPoints
delegate: Rectangle {
width: dargWidth
height: dargWidth
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,
canvas.height).x - width / 2
y: scaledPoint(modelData, canvas.width,
canvas.height).y - height / 2
}
}
MouseArea {
anchors.fill: parent
property int draggedOpenDoorAreaPointIndex: -1
property int draggedShieldedAreaPointIndex: -1
property int draggedAntiAreaPointIndex: -1
onPressed: mouse => {
if(openDoorAreaEnabled){
for (var i = 0; i < openDoorAreaPoints.length; i++) {
let point = scaledPoint(
openDoorAreaPoints[i], canvas.width,
canvas.height)
if (isInside(mouse.x, mouse.y, point)) {
draggedOpenDoorAreaPointIndex = i
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: {
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 => {
if ((mouse.x < 0) || (mouse.x > canvas.width) || (mouse.y < 0) || (mouse.y > canvas.height)) return
if (draggedOpenDoorAreaPointIndex >= 0) {
openDoorAreaPoints[draggedOpenDoorAreaPointIndex]
= standardPoint(Qt.point(mouse.x, mouse.y), canvas.width, canvas.height)
canvas.requestPaint()
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
}
}
function isInside(x, y, point) {
let edge = dargWidth / 2
return x >= point.x - edge && x <= point.x + edge
&& y >= point.y - edge && y <= point.y + edge
} }
} }
} }
}
Repeater { Row {
id: repeater id: controlBar
model: openDoorAreaPoints anchors.left: parent.left
delegate: Rectangle { anchors.right: parent.right
width: dargWidth anchors.bottom: parent.bottom
height: dargWidth Switch {
color: "red" text: "开门区域"
x: scaledPoint(modelData, canvas.width, checked: openDoorAreaEnabled
canvas.height).x - width / 2 onToggled: App.currentOpenDoorAreaEnabled = checked
y: scaledPoint(modelData, canvas.width,
canvas.height).y - height / 2
}
} }
Switch {
MouseArea { text: "防夹区域"
anchors.fill: parent checked: antiClipAreaEnabled
property int draggedPointIndex: -1 onToggled: App.currentAntiClipAreaEnabled = checked
onPressed: mouse => { }
for (var i = 0; i < openDoorAreaPoints.length; i++) { Switch {
let point = scaledPoint(openDoorAreaPoints[i], text: "屏蔽区域"
canvas.width, checked: shieldedAreaEnabled
canvas.height) onToggled: App.currentShieldedAreaEnabled = checked
if (isInside(mouse.x, mouse.y, point)) {
draggedPointIndex = i
break
}
}
}
onReleased: {
draggedPointIndex = -1
}
onPositionChanged: mouse => {
if (draggedPointIndex >= 0) {
openDoorAreaPoints[draggedPointIndex] = standardPoint(
Qt.point(mouse.x, mouse.y),
canvas.width, canvas.height)
canvas.requestPaint()
repeater.model = openDoorAreaPoints
}
}
function isInside(x, y, point) {
let edge = dargWidth / 2
return x >= point.x - edge && x <= point.x + edge
&& y >= point.y - edge && y <= point.y + edge
}
} }
} }
// //
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)
} }
// (640x360)
function standardPoint(point, width, height) { function standardPoint(point, width, height) {
// (640x360)
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()
}
} }
} }

View File

@ -1,22 +1,32 @@
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 {
Button { RowLayout {
text: "连接" anchors.fill: parent
onClicked: App.open() Button {
} text: "搜索设备"
}
Button { Button {
text: "开始" text: "连接"
onClicked: App.start() onClicked: App.open()
}
Button {
text: "开始"
onClicked: App.start()
}
Text {
Layout.alignment: Qt.AlignRight
text: qsTr("当前设备版本号: RD_T009_V02R001B001")
}
} }
} }
@ -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
} }
} }