初步实现网络修改。
This commit is contained in:
parent
0f24d95eee
commit
f59645700a
109
Application.cpp
109
Application.cpp
@ -1,7 +1,6 @@
|
||||
#include "Application.h"
|
||||
#include "BoostLog.h"
|
||||
#include "Configuration.h"
|
||||
#include "DeviceConnection.h"
|
||||
#include "H264Palyer.h"
|
||||
#include "VideoFrameProvider.h"
|
||||
#include <QFont>
|
||||
@ -10,7 +9,7 @@
|
||||
|
||||
Application::Application(int &argc, char **argv)
|
||||
: m_app(std::make_shared<QGuiApplication>(argc, argv)), m_videoFrameProvider(new VideoFrameProvider()),
|
||||
m_player(std::make_shared<H264Palyer>()) {
|
||||
m_player(std::make_shared<H264Palyer>()), m_devices(new DeviceListModel(this)) {
|
||||
QFont font;
|
||||
font.setPointSize(16);
|
||||
m_app->setFont(font);
|
||||
@ -19,20 +18,30 @@ Application::Application(int &argc, char **argv)
|
||||
m_player->open();
|
||||
}
|
||||
|
||||
bool Application::currentOpenDoorAreaEnabled() const {
|
||||
return m_currentOpenDoorAreaEnabled;
|
||||
DeviceConnection::AreaWay Application::currentOpenDoorAreaWay() const {
|
||||
return m_currentOpenDoorAreaWay;
|
||||
}
|
||||
|
||||
void Application::setCurrentOpenDoorAreaEnabled(bool enabled) {
|
||||
if (m_currentOpenDoorAreaEnabled != enabled) {
|
||||
m_currentOpenDoorAreaEnabled = enabled;
|
||||
emit currentOpenDoorAreaEnabledChanged();
|
||||
void Application::setCurrentOpenDoorAreaWay(DeviceConnection::AreaWay way) {
|
||||
if (m_currentOpenDoorAreaWay == way) return;
|
||||
m_currentOpenDoorAreaWay = way;
|
||||
if (m_currentOpenDoorAreaWay == DeviceConnection::Quadrangle) {
|
||||
if ((m_currentOpenDoorAreaPoints.size() < 4) || (m_currentOpenDoorAreaPoints == FullArea)) {
|
||||
m_currentOpenDoorAreaPoints.clear();
|
||||
m_currentOpenDoorAreaPoints << QPointF(68, 6) << QPointF(570, 6) << QPointF(570, 354) << QPointF(68, 354);
|
||||
emit currentOpenDoorAreaPointsChanged();
|
||||
}
|
||||
} else if (m_currentOpenDoorAreaWay == DeviceConnection::FullArea) {
|
||||
m_currentOpenDoorAreaPoints.clear();
|
||||
m_currentOpenDoorAreaPoints = FullArea;
|
||||
emit currentOpenDoorAreaPointsChanged();
|
||||
}
|
||||
|
||||
emit currentOpenDoorAreaWayChanged();
|
||||
if (m_device != nullptr) {
|
||||
m_device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaEnabled, m_currentOpenDoorAreaPoints);
|
||||
m_device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaWay, m_currentOpenDoorAreaPoints);
|
||||
}
|
||||
}
|
||||
LOG(info) << "setCurrentOpenDoorAreaEnabled " << enabled;
|
||||
}
|
||||
|
||||
QList<QPointF> Application::currentOpenDoorAreaPoints() const {
|
||||
return m_currentOpenDoorAreaPoints;
|
||||
@ -45,6 +54,10 @@ void Application::setCurrentOpenDoorAreaPoints(const QList<QPointF> &points) {
|
||||
}
|
||||
}
|
||||
|
||||
NetworkInfomation Application::currentNetworkInfomation() const {
|
||||
return m_currentNetworkInfomation;
|
||||
}
|
||||
|
||||
bool Application::currentShieldedAreaEnabled() const {
|
||||
return m_currentShieldedAreaEnabled;
|
||||
}
|
||||
@ -53,6 +66,13 @@ void Application::setCurrentShieldedAreaEnabled(bool enabled) {
|
||||
if (m_currentShieldedAreaEnabled != enabled) {
|
||||
m_currentShieldedAreaEnabled = enabled;
|
||||
emit currentShieldedAreaEnabledChanged();
|
||||
|
||||
if (m_currentShieldedAreaPoints.size() < 4) {
|
||||
m_currentShieldedAreaPoints.clear();
|
||||
m_currentShieldedAreaPoints << QPointF(6, 6) << QPointF(40, 60) << QPointF(590, 6) << QPointF(630, 60);
|
||||
emit currentShieldedAreaPointsChanged();
|
||||
}
|
||||
|
||||
if (m_device != nullptr) {
|
||||
m_device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, m_currentShieldedAreaPoints);
|
||||
}
|
||||
@ -96,8 +116,9 @@ void Application::setCurrentAntiClipAreaPoints(const QList<QPointF> &points) {
|
||||
}
|
||||
|
||||
void Application::updateOpenDoorAreaPoints(const QList<QPointF> &points) {
|
||||
LOG(info) << "updateOpenDoorAreaPoints: " << points.size();
|
||||
m_device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaEnabled, points);
|
||||
if (m_device != nullptr) {
|
||||
m_device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaWay, points);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::updateAntiClipAreaPoints(const QList<QPointF> &points) {
|
||||
@ -108,10 +129,39 @@ void Application::updateShieldedAreaPoints(const QList<QPointF> &points) {
|
||||
m_device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, points);
|
||||
}
|
||||
|
||||
void Application::onDeviceOpenDoorArea(bool enabled, const QList<QPointF> &points) {
|
||||
setCurrentOpenDoorAreaEnabled(enabled);
|
||||
void Application::updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask,
|
||||
const QString &gateway) {
|
||||
LOG(info) << dhcp;
|
||||
LOG(info) << ip.toStdString();
|
||||
if (m_device != nullptr) {
|
||||
m_device->updateNetworkInfomation(dhcp, ip, netmask, gateway);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::connectToDevice(const QString &address) {
|
||||
if (m_device != nullptr) {
|
||||
m_device->deleteLater();
|
||||
}
|
||||
|
||||
m_device = new DeviceConnection();
|
||||
connect(m_device, &DeviceConnection::currentOpenDoorAreaChanged, this, &Application::onDeviceOpenDoorArea);
|
||||
connect(m_device, &DeviceConnection::currentShieldedAreaChanged, this, &Application::onDeviceShieldedArea);
|
||||
connect(m_device, &DeviceConnection::currentAntiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
|
||||
connect(m_device, &DeviceConnection::currentNetworkInfomationChanged, this,
|
||||
&Application::onDeviceNetworkInfomation);
|
||||
m_device->connect(address);
|
||||
m_device->setH264FrameCallback([this](const char *data, uint32_t size) {
|
||||
auto image = m_player->decode((const uint8_t *)data, size);
|
||||
if (image) {
|
||||
m_videoFrameProvider->setImage(*image);
|
||||
emit newVideoFrame();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Application::onDeviceOpenDoorArea(DeviceConnection::AreaWay way, const QList<QPointF> &points) {
|
||||
setCurrentOpenDoorAreaWay(way);
|
||||
setCurrentOpenDoorAreaPoints(points);
|
||||
LOG(info) << "onDeviceOpenDoorAreaPoints: " << points.size();
|
||||
}
|
||||
|
||||
void Application::onDeviceShieldedArea(bool enabled, const QList<QPointF> &points) {
|
||||
@ -125,6 +175,11 @@ void Application::onDeviceAntiClipArea(bool enabled, const QList<QPointF> &point
|
||||
setCurrentAntiClipAreaPoints(points);
|
||||
}
|
||||
|
||||
void Application::onDeviceNetworkInfomation(const NetworkInfomation &info) {
|
||||
m_currentNetworkInfomation = info;
|
||||
emit currentNetworkInfomationChanged();
|
||||
}
|
||||
|
||||
int Application::exec() {
|
||||
QQmlApplicationEngine engine;
|
||||
engine.addImageProvider("videoframe", m_videoFrameProvider);
|
||||
@ -135,28 +190,6 @@ int Application::exec() {
|
||||
return m_app->exec();
|
||||
}
|
||||
|
||||
void Application::open() {
|
||||
LOG(info) << "Application::start";
|
||||
m_device = new DeviceConnection();
|
||||
connect(m_device, &DeviceConnection::currentOpenDoorAreaChanged, this, &Application::onDeviceOpenDoorArea);
|
||||
connect(m_device, &DeviceConnection::currentShieldedAreaChanged, this, &Application::onDeviceShieldedArea);
|
||||
connect(m_device, &DeviceConnection::currentAntiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
|
||||
m_device->connect();
|
||||
m_device->setH264FrameCallback([this](const char *data, uint32_t size) {
|
||||
auto image = m_player->decode((const uint8_t *)data, size);
|
||||
if (image) {
|
||||
m_videoFrameProvider->setImage(*image);
|
||||
emit newVideoFrame();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Application::start() {
|
||||
if (m_device != nullptr) {
|
||||
m_device->start();
|
||||
}
|
||||
}
|
||||
|
||||
Application *Application::create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) {
|
||||
Application *ret = nullptr;
|
||||
auto app = Amass::Singleton<Application>::instance();
|
||||
|
@ -1,13 +1,15 @@
|
||||
#ifndef APPLICATION_H
|
||||
#define APPLICATION_H
|
||||
|
||||
#include "DataStructure.h"
|
||||
#include "DeviceConnection.h"
|
||||
#include "DeviceListModel.h"
|
||||
#include "Singleton.h"
|
||||
#include <QObject>
|
||||
#include <QPoint>
|
||||
#include <QQmlEngine>
|
||||
|
||||
class QGuiApplication;
|
||||
class DeviceConnection;
|
||||
class VideoFrameProvider;
|
||||
class H264Palyer;
|
||||
|
||||
@ -16,8 +18,10 @@ class Application : public QObject {
|
||||
QML_NAMED_ELEMENT(App)
|
||||
QML_SINGLETON
|
||||
Q_PROPERTY(int DeviceWidth MEMBER DeviceWidth CONSTANT FINAL)
|
||||
Q_PROPERTY(bool currentOpenDoorAreaEnabled READ currentOpenDoorAreaEnabled WRITE setCurrentOpenDoorAreaEnabled
|
||||
NOTIFY currentOpenDoorAreaEnabledChanged)
|
||||
Q_PROPERTY(int DeviceHeight MEMBER DeviceHeight CONSTANT FINAL)
|
||||
Q_PROPERTY(DeviceListModel *devices MEMBER m_devices CONSTANT FINAL);
|
||||
Q_PROPERTY(DeviceConnection::AreaWay currentOpenDoorAreaWay READ currentOpenDoorAreaWay WRITE
|
||||
setCurrentOpenDoorAreaWay NOTIFY currentOpenDoorAreaWayChanged)
|
||||
Q_PROPERTY(QList<QPointF> currentOpenDoorAreaPoints READ currentOpenDoorAreaPoints WRITE
|
||||
setCurrentOpenDoorAreaPoints NOTIFY currentOpenDoorAreaPointsChanged)
|
||||
Q_PROPERTY(bool currentShieldedAreaEnabled READ currentShieldedAreaEnabled WRITE setCurrentShieldedAreaEnabled
|
||||
@ -28,15 +32,22 @@ class Application : public QObject {
|
||||
NOTIFY currentAntiClipAreaEnabledChanged)
|
||||
Q_PROPERTY(QList<QPointF> currentAntiClipAreaPoints READ currentAntiClipAreaPoints WRITE
|
||||
setCurrentAntiClipAreaPoints NOTIFY currentAntiClipAreaPointsChanged)
|
||||
Q_PROPERTY(
|
||||
NetworkInfomation currentNetworkInfomation READ currentNetworkInfomation NOTIFY currentNetworkInfomationChanged)
|
||||
friend class Amass::Singleton<Application>;
|
||||
|
||||
public:
|
||||
constexpr static int DeviceWidth = 640;
|
||||
bool currentOpenDoorAreaEnabled() const;
|
||||
void setCurrentOpenDoorAreaEnabled(bool enabled);
|
||||
constexpr static int DeviceHeight = 360;
|
||||
inline static const QList<QPointF> FullArea = {QPointF(0, 0), QPointF(DeviceWidth, 0),
|
||||
QPointF(DeviceWidth, DeviceHeight), QPointF(0, DeviceHeight)};
|
||||
DeviceConnection::AreaWay currentOpenDoorAreaWay() const;
|
||||
void setCurrentOpenDoorAreaWay(DeviceConnection::AreaWay way);
|
||||
QList<QPointF> currentOpenDoorAreaPoints() const;
|
||||
void setCurrentOpenDoorAreaPoints(const QList<QPointF> &points);
|
||||
|
||||
NetworkInfomation currentNetworkInfomation() const;
|
||||
|
||||
bool currentShieldedAreaEnabled() const;
|
||||
void setCurrentShieldedAreaEnabled(bool enabled);
|
||||
QList<QPointF> currentShieldedAreaPoints() const;
|
||||
@ -50,10 +61,11 @@ public:
|
||||
Q_INVOKABLE void updateOpenDoorAreaPoints(const QList<QPointF> &points);
|
||||
Q_INVOKABLE void updateAntiClipAreaPoints(const QList<QPointF> &points);
|
||||
Q_INVOKABLE void updateShieldedAreaPoints(const QList<QPointF> &points);
|
||||
Q_INVOKABLE void updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask,
|
||||
const QString &gateway);
|
||||
Q_INVOKABLE void connectToDevice(const QString &address);
|
||||
|
||||
int exec();
|
||||
Q_INVOKABLE void open();
|
||||
Q_INVOKABLE void start();
|
||||
static Application *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine);
|
||||
|
||||
signals:
|
||||
@ -61,28 +73,32 @@ signals:
|
||||
void currentOpenDoorAreaPointsChanged();
|
||||
void currentShieldedAreaPointsChanged();
|
||||
void currentAntiClipAreaPointsChanged();
|
||||
void currentOpenDoorAreaEnabledChanged();
|
||||
void currentOpenDoorAreaWayChanged();
|
||||
void currentShieldedAreaEnabledChanged();
|
||||
void currentAntiClipAreaEnabledChanged();
|
||||
void currentNetworkInfomationChanged();
|
||||
|
||||
protected:
|
||||
Application(int &argc, char **argv);
|
||||
void onDeviceOpenDoorArea(bool enabled, const QList<QPointF> &points);
|
||||
void onDeviceOpenDoorArea(DeviceConnection::AreaWay way, const QList<QPointF> &points);
|
||||
void onDeviceShieldedArea(bool enabled, const QList<QPointF> &points);
|
||||
void onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points);
|
||||
void onDeviceNetworkInfomation(const NetworkInfomation &info);
|
||||
|
||||
private:
|
||||
std::shared_ptr<QGuiApplication> m_app;
|
||||
VideoFrameProvider *m_videoFrameProvider = nullptr;
|
||||
std::shared_ptr<H264Palyer> m_player;
|
||||
DeviceConnection *m_device = nullptr;
|
||||
DeviceListModel *m_devices = nullptr;
|
||||
|
||||
bool m_currentOpenDoorAreaEnabled = false;
|
||||
DeviceConnection::AreaWay m_currentOpenDoorAreaWay = DeviceConnection::Diabled;
|
||||
QList<QPointF> m_currentOpenDoorAreaPoints;
|
||||
bool m_currentShieldedAreaEnabled = false;
|
||||
QList<QPointF> m_currentShieldedAreaPoints;
|
||||
bool m_currentAntiClipAreaEnabled = false;
|
||||
QList<QPointF> m_currentAntiClipAreaPoints;
|
||||
NetworkInfomation m_currentNetworkInfomation;
|
||||
};
|
||||
|
||||
#endif // APPLICATION_H
|
||||
|
@ -9,8 +9,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(Projects_ROOT E:/Projects)
|
||||
set(Libraries_ROOT ${Projects_ROOT}/Libraries)
|
||||
|
||||
set(BOOST_ROOT ${Libraries_ROOT}/boost_1_85_0_msvc2022_64bit)
|
||||
set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include/boost-1_85)
|
||||
set(BOOST_ROOT ${Libraries_ROOT}/boost_1_86_0_msvc2022_64bit)
|
||||
set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include/boost-1_86)
|
||||
option(Boost_USE_STATIC_LIBS OFF)
|
||||
add_compile_definitions(
|
||||
BOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WIN10
|
||||
@ -21,7 +21,7 @@ set(FFmpeg_INCLUDE_DIR ${FFmpeg_ROOT}/include)
|
||||
set(FFmpeg_LIB_DIR ${FFmpeg_ROOT}/lib)
|
||||
|
||||
find_package(Boost REQUIRED COMPONENTS json)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Qml Quick)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Qml Quick Network)
|
||||
|
||||
qt_standard_project_setup(REQUIRES 6.5)
|
||||
|
||||
@ -36,7 +36,9 @@ qt_add_executable(AntiClipSettings
|
||||
AntiClipSettings.rc
|
||||
main.cpp
|
||||
Application.h Application.cpp
|
||||
DataStructure.h
|
||||
DeviceConnection.h DeviceConnection.cpp
|
||||
DeviceListModel.h DeviceListModel.cpp
|
||||
H264Palyer.h H264Palyer.cpp
|
||||
VideoFrameProvider.h VideoFrameProvider.cpp
|
||||
)
|
||||
@ -46,6 +48,7 @@ qt_add_qml_module(AntiClipSettings
|
||||
QML_FILES
|
||||
Main.qml
|
||||
DeviceView.qml
|
||||
NetworkSettingPopup.qml
|
||||
)
|
||||
|
||||
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
|
||||
@ -73,6 +76,7 @@ target_link_directories(AntiClipSettings
|
||||
target_link_libraries(AntiClipSettings
|
||||
PRIVATE Qt6::Qml
|
||||
PRIVATE Qt6::Quick
|
||||
PRIVATE Qt6::Network
|
||||
PRIVATE Boost::json
|
||||
PRIVATE avcodec
|
||||
PRIVATE swscale
|
||||
|
22
DataStructure.h
Normal file
22
DataStructure.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef __DATASTRUCTURE_H__
|
||||
#define __DATASTRUCTURE_H__
|
||||
|
||||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
|
||||
struct NetworkInfomation {
|
||||
Q_GADGET
|
||||
QML_NAMED_ELEMENT(networkInfomation)
|
||||
Q_PROPERTY(bool dhcp MEMBER dhcp)
|
||||
Q_PROPERTY(QString ip MEMBER ip)
|
||||
Q_PROPERTY(QString netmask MEMBER netmask)
|
||||
Q_PROPERTY(QString gateway MEMBER gateway)
|
||||
public:
|
||||
bool dhcp;
|
||||
QString ip = "127.0..1";
|
||||
QString netmask;
|
||||
QString gateway;
|
||||
};
|
||||
Q_DECLARE_METATYPE(NetworkInfomation)
|
||||
|
||||
#endif // __DATASTRUCTURE_H__
|
@ -1,7 +1,6 @@
|
||||
#include "DeviceConnection.h"
|
||||
#include "BoostLog.h"
|
||||
#include <QPointF>
|
||||
#include <QTcpSocket>
|
||||
#include <WinSock2.h>
|
||||
#include <boost/json/object.hpp>
|
||||
#include <boost/json/parse.hpp>
|
||||
@ -10,7 +9,7 @@
|
||||
DeviceConnection::DeviceConnection(QObject *parent) : QObject{parent} {
|
||||
}
|
||||
|
||||
void DeviceConnection::connect() {
|
||||
void DeviceConnection::connect(const QString &address) {
|
||||
m_commandSocket = new QTcpSocket(this);
|
||||
m_h264Socket = new QTcpSocket(this);
|
||||
|
||||
@ -20,8 +19,8 @@ void DeviceConnection::connect() {
|
||||
QObject::connect(m_h264Socket, &QTcpSocket::readyRead, this, &DeviceConnection::onH264ReadyRead);
|
||||
QObject::connect(m_commandSocket, &QTcpSocket::readyRead, this, &DeviceConnection::onCommandReadyRead);
|
||||
|
||||
m_commandSocket->connectToHost("192.168.10.2", 8000);
|
||||
m_h264Socket->connectToHost("192.168.10.2", 8000);
|
||||
m_commandSocket->connectToHost(address, 8000);
|
||||
m_h264Socket->connectToHost(address, 8000);
|
||||
}
|
||||
|
||||
void DeviceConnection::start() {
|
||||
@ -53,13 +52,19 @@ void DeviceConnection::requestOpenDoorArea() {
|
||||
m_requests.push(task);
|
||||
}
|
||||
|
||||
void DeviceConnection::updateOpenDoorAreaPoints(bool enabled, const QList<QPointF> &points) {
|
||||
auto task = [this, enabled, points]() {
|
||||
void DeviceConnection::updateOpenDoorAreaPoints(AreaWay way, const QList<QPointF> &points) {
|
||||
auto task = [this, way, points]() {
|
||||
boost::json::object request;
|
||||
request["func"] = "a03opendoor1_setdata";
|
||||
request["deviceid"] = "0";
|
||||
boost::json::object data;
|
||||
data["value"] = enabled ? "1" : "0";
|
||||
const char *value = "0";
|
||||
if (way == FullArea) {
|
||||
value = "1";
|
||||
} else if (way == Quadrangle) {
|
||||
value = "2";
|
||||
}
|
||||
data["value"] = value;
|
||||
boost::json::array pointArray;
|
||||
for (auto &p : points) {
|
||||
boost::json::object point;
|
||||
@ -186,6 +191,46 @@ void DeviceConnection::requestResolution(Resolution resolution) {
|
||||
m_requests.push(task);
|
||||
}
|
||||
|
||||
void DeviceConnection::requestNetworkInfomation() {
|
||||
auto task = [this]() {
|
||||
boost::json::object request;
|
||||
request["func"] = "netconfig_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) << "requestNetworkInfomation";
|
||||
};
|
||||
if (m_requests.empty()) {
|
||||
task();
|
||||
}
|
||||
m_requests.push(task);
|
||||
}
|
||||
|
||||
void DeviceConnection::updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask,
|
||||
const QString &gateway) {
|
||||
auto task = [this, dhcp, ip, netmask, gateway]() {
|
||||
boost::json::object request;
|
||||
request["func"] = "netconfig_setdata";
|
||||
request["deviceid"] = "0";
|
||||
boost::json::object data;
|
||||
data["type"] = dhcp ? "dhcp" : "static";
|
||||
data["ip"] = ip.toStdString();
|
||||
data["netmask"] = netmask.toStdString();
|
||||
data["gateway"] = gateway.toStdString();
|
||||
|
||||
request["data"] = std::move(data);
|
||||
auto text = boost::json::serialize(request);
|
||||
m_commandSocket->write(text.data(), text.size());
|
||||
LOG(info) << "requestUpdateNetworkInfomation";
|
||||
};
|
||||
if (m_requests.empty()) {
|
||||
task();
|
||||
}
|
||||
m_requests.push(task);
|
||||
}
|
||||
|
||||
void DeviceConnection::handleCommand(const std::string_view &replyText) {
|
||||
boost::system::error_code error;
|
||||
auto replyValue = boost::json::parse(replyText, error);
|
||||
@ -207,7 +252,13 @@ void DeviceConnection::handleCommand(const std::string_view &replyText) {
|
||||
point.setY(obj.at("y").as_double());
|
||||
points.push_back(point);
|
||||
}
|
||||
emit currentOpenDoorAreaChanged(value == "1", points);
|
||||
AreaWay way = Diabled;
|
||||
if (value == "1") {
|
||||
way = FullArea;
|
||||
} else if (value == "2") {
|
||||
way = Quadrangle;
|
||||
}
|
||||
emit currentOpenDoorAreaChanged(way, points);
|
||||
} else if (function == "a03opendoor4_getdata") {
|
||||
auto &data = reply.at("data").as_object();
|
||||
auto &value = data.at("value").as_string();
|
||||
@ -234,6 +285,14 @@ void DeviceConnection::handleCommand(const std::string_view &replyText) {
|
||||
points.push_back(point);
|
||||
}
|
||||
emit currentAntiClipAreaChanged(value == "1", points);
|
||||
} else if (function == "netconfig_getdata") {
|
||||
auto &data = reply.at("data").as_object();
|
||||
NetworkInfomation info;
|
||||
info.dhcp = data.at("type").as_string() == "dhcp";
|
||||
info.ip = data.at("ip").as_string().c_str();
|
||||
info.gateway = data.at("gateway").as_string().c_str();
|
||||
info.netmask = data.at("netmask").as_string().c_str();
|
||||
emit currentNetworkInfomationChanged(info);
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,6 +303,9 @@ void DeviceConnection::onConnected() {
|
||||
requestOpenDoorArea();
|
||||
requestShieldedArea();
|
||||
requestAntiClipArea();
|
||||
requestNetworkInfomation();
|
||||
} else if (socket == m_h264Socket) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,19 @@
|
||||
#ifndef DEVICECONNECTION_H
|
||||
#define DEVICECONNECTION_H
|
||||
|
||||
#include "DataStructure.h"
|
||||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
#include <QTcpSocket>
|
||||
#include <queue>
|
||||
#include <string_view>
|
||||
class QTcpSocket;
|
||||
|
||||
class NetworkInfomation;
|
||||
|
||||
class DeviceConnection : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("Only used in C++...")
|
||||
QML_UNCREATABLE("Only created in C++...")
|
||||
|
||||
public:
|
||||
enum Resolution {
|
||||
@ -19,33 +22,37 @@ public:
|
||||
};
|
||||
enum AreaWay {
|
||||
Diabled = 0,
|
||||
FullScreen,
|
||||
FullArea,
|
||||
Quadrangle, // 四边形
|
||||
};
|
||||
Q_ENUM(AreaWay)
|
||||
using H264FrameCallback = std::function<void(const char *data, uint32_t size)>;
|
||||
explicit DeviceConnection(QObject *parent = nullptr);
|
||||
void setH264FrameCallback(H264FrameCallback &&callback);
|
||||
void connect();
|
||||
void connect(const QString &address);
|
||||
void start();
|
||||
void requestOpenDoorArea();
|
||||
void updateOpenDoorAreaPoints(bool enabled, const QList<QPointF> &points);
|
||||
void updateOpenDoorAreaPoints(AreaWay way, 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);
|
||||
void requestNetworkInfomation();
|
||||
void updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway);
|
||||
|
||||
signals:
|
||||
void currentOpenDoorAreaChanged(bool enabled, const QList<QPointF> &points);
|
||||
void currentOpenDoorAreaChanged(AreaWay way, const QList<QPointF> &points);
|
||||
void currentShieldedAreaChanged(bool enabled, const QList<QPointF> &points);
|
||||
void currentAntiClipAreaChanged(bool enabled, const QList<QPointF> &points);
|
||||
void currentNetworkInfomationChanged(const NetworkInfomation &info);
|
||||
|
||||
protected:
|
||||
void onConnected();
|
||||
void onH264ReadyRead();
|
||||
void onCommandReadyRead();
|
||||
void handleCommand(const std::string_view &replyText);
|
||||
void onErrorOccurred(QAbstractSocket::SocketError socketError);
|
||||
|
||||
private:
|
||||
QTcpSocket *m_commandSocket = nullptr;
|
||||
|
161
DeviceListModel.cpp
Normal file
161
DeviceListModel.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
#include "DeviceListModel.h"
|
||||
#include "BoostLog.h"
|
||||
#include <QNetworkDatagram>
|
||||
#include <QNetworkInterface>
|
||||
#include <QTimer>
|
||||
#include <QUdpSocket>
|
||||
#include <boost/json/parse.hpp>
|
||||
|
||||
DeviceListModel::DeviceListModel(QObject *parent) : QAbstractListModel{parent} {
|
||||
m_broadcastSocket = new QUdpSocket(this);
|
||||
}
|
||||
|
||||
int DeviceListModel::rowCount(const QModelIndex &parent) const {
|
||||
return m_devices.size();
|
||||
}
|
||||
|
||||
QVariant DeviceListModel::data(const QModelIndex &index, int role) const {
|
||||
QVariant ret;
|
||||
auto row = index.row();
|
||||
if (role == DeviceIdRole) {
|
||||
ret = m_devices.at(row).deviceId;
|
||||
} else if (role == FirmwareVersionRole) {
|
||||
ret = m_devices.at(row).firmwareVersion;
|
||||
} else if (role == SoftwareVersionRole) {
|
||||
ret = m_devices.at(row).softwareVersion;
|
||||
} else if (role == IpRole) {
|
||||
ret = m_devices.at(row).ip;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> DeviceListModel::roleNames() const {
|
||||
QHash<int, QByteArray> roleNames;
|
||||
roleNames.insert(DeviceIdRole, "deviceId");
|
||||
roleNames.insert(FirmwareVersionRole, "firmwareVersion");
|
||||
roleNames.insert(SoftwareVersionRole, "softwareVersion");
|
||||
roleNames.insert(IpRole, "ip");
|
||||
return roleNames;
|
||||
}
|
||||
|
||||
QVariantMap DeviceListModel::get(int index) const {
|
||||
QVariantMap map;
|
||||
if (index >= 0 && index < m_devices.size()) {
|
||||
map["firmwareVersion"] = m_devices[index].firmwareVersion;
|
||||
map["softwareVersion"] = m_devices[index].softwareVersion;
|
||||
map["deviceId"] = m_devices[index].deviceId;
|
||||
map["ip"] = m_devices[index].ip;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
void DeviceListModel::startSearchDevice() {
|
||||
if (m_timerId >= 0) {
|
||||
LOG(error) << "app is searching device.";
|
||||
return;
|
||||
}
|
||||
beginResetModel();
|
||||
m_devices.clear();
|
||||
endResetModel();
|
||||
auto interfaces = QNetworkInterface::allInterfaces();
|
||||
for (auto &interface : interfaces) {
|
||||
if (interface.flags() & QNetworkInterface::IsLoopBack) continue;
|
||||
if (interface.flags() & QNetworkInterface::IsUp && interface.flags() & QNetworkInterface::IsRunning) {
|
||||
const QList<QNetworkAddressEntry> entries = interface.addressEntries();
|
||||
for (const QNetworkAddressEntry &entry : entries) {
|
||||
if (entry.ip().protocol() != QAbstractSocket::IPv4Protocol) continue;
|
||||
QUdpSocket *socket = new QUdpSocket(this);
|
||||
if (socket->bind(entry.ip(), ListenPort, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) {
|
||||
connect(socket, &QUdpSocket::readyRead, this, &DeviceListModel::onDeviceReplyReadyRead);
|
||||
m_udpSockets.push_back(socket);
|
||||
LOG(info) << "Listening on " << entry.ip().toString().toStdString() << ":" << ListenPort;
|
||||
} else {
|
||||
LOG(error) << "Failed to bind UDP socket on" << entry.ip().toString().toStdString() << ":"
|
||||
<< ListenPort;
|
||||
delete socket;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!m_udpSockets.empty()) {
|
||||
m_retries = 0;
|
||||
emit searchProgressChanged();
|
||||
m_timerId = startTimer(1000);
|
||||
emit isSearchingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceListModel::isSearching() const {
|
||||
return m_timerId >= 0;
|
||||
}
|
||||
|
||||
float DeviceListModel::searchProgress() const {
|
||||
return static_cast<float>(m_retries) * 100 / RetryCount;
|
||||
}
|
||||
|
||||
void DeviceListModel::onDeviceReplyReadyRead() {
|
||||
auto udp = dynamic_cast<QUdpSocket *>(sender());
|
||||
while (udp->hasPendingDatagrams()) {
|
||||
QNetworkDatagram datagram = udp->receiveDatagram();
|
||||
auto replyVale = boost::json::parse(datagram.data().toStdString());
|
||||
auto &reply = replyVale.as_object();
|
||||
DeviceInfomation device;
|
||||
device.deviceId = QString::fromStdString(std::string(reply.at("devid").as_string()));
|
||||
device.firmwareVersion = QString::fromStdString(std::string(reply.at("fw_ver").as_string()));
|
||||
device.softwareVersion = QString::fromStdString(std::string(reply.at("sw_ver").as_string()));
|
||||
device.ip = datagram.senderAddress().toString();
|
||||
|
||||
auto iterator = std::find_if(m_devices.cbegin(), m_devices.cend(), [&device](const DeviceInfomation &item) {
|
||||
return item.deviceId == device.deviceId;
|
||||
});
|
||||
if (iterator == m_devices.cend()) {
|
||||
beginInsertRows(QModelIndex(), m_devices.size(), m_devices.size());
|
||||
m_devices.push_back(device);
|
||||
endInsertRows();
|
||||
}
|
||||
LOG(info) << "Received datagram from " << datagram.senderAddress().toString().toStdString() << ":"
|
||||
<< datagram.senderPort() << ", Data: " << datagram.data().toStdString();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceListModel::broadcast() {
|
||||
if (m_udpSockets.empty()) return;
|
||||
QByteArray datagram = "FACEPASS_V2";
|
||||
auto interfaces = QNetworkInterface::allInterfaces();
|
||||
for (auto &interface : interfaces) {
|
||||
if (interface.flags() & QNetworkInterface::IsLoopBack) continue;
|
||||
if (interface.flags() & QNetworkInterface::IsUp && interface.flags() & QNetworkInterface::IsRunning) {
|
||||
const QList<QNetworkAddressEntry> entries = interface.addressEntries();
|
||||
for (const QNetworkAddressEntry &entry : entries) {
|
||||
if (entry.broadcast().toIPv4Address()) {
|
||||
m_broadcastSocket->writeDatagram(datagram, entry.broadcast(), BroadcastPort);
|
||||
LOG(info) << "Broadcasted datagram: " << datagram.toStdString() << " to "
|
||||
<< entry.broadcast().toString().toStdString() << ":" << BroadcastPort;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceListModel::stopSearchDevice() {
|
||||
if (m_timerId >= 0) {
|
||||
killTimer(m_timerId);
|
||||
m_timerId = -1;
|
||||
}
|
||||
if (!m_udpSockets.empty()) {
|
||||
for (auto &socket : m_udpSockets) {
|
||||
socket->deleteLater();
|
||||
}
|
||||
m_udpSockets.clear();
|
||||
}
|
||||
emit isSearchingChanged();
|
||||
}
|
||||
|
||||
void DeviceListModel::timerEvent(QTimerEvent *event) {
|
||||
broadcast();
|
||||
m_retries++;
|
||||
emit searchProgressChanged();
|
||||
if (m_retries >= RetryCount) {
|
||||
QTimer::singleShot(0, this, &DeviceListModel::stopSearchDevice);
|
||||
}
|
||||
}
|
61
DeviceListModel.h
Normal file
61
DeviceListModel.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef DEVICELISTMODEL_H
|
||||
#define DEVICELISTMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QQmlEngine>
|
||||
|
||||
class QUdpSocket;
|
||||
|
||||
class DeviceInfomation {
|
||||
public:
|
||||
QString deviceId;
|
||||
QString softwareVersion;
|
||||
QString firmwareVersion;
|
||||
QString ip;
|
||||
};
|
||||
|
||||
class DeviceListModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("Only used in C++...")
|
||||
Q_PROPERTY(bool isSearching READ isSearching NOTIFY isSearchingChanged)
|
||||
Q_PROPERTY(float searchProgress READ searchProgress NOTIFY searchProgressChanged)
|
||||
|
||||
public:
|
||||
static constexpr uint16_t BroadcastPort = 40000;
|
||||
static constexpr uint16_t ListenPort = 40001;
|
||||
static constexpr int RetryCount = 10;
|
||||
enum InfoRoles {
|
||||
DeviceIdRole = Qt::UserRole + 1,
|
||||
FirmwareVersionRole,
|
||||
SoftwareVersionRole,
|
||||
IpRole,
|
||||
};
|
||||
DeviceListModel(QObject *parent = nullptr);
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const final;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const final;
|
||||
QHash<int, QByteArray> roleNames() const final;
|
||||
Q_INVOKABLE QVariantMap get(int index) const;
|
||||
Q_INVOKABLE void startSearchDevice();
|
||||
bool isSearching() const;
|
||||
float searchProgress() const;
|
||||
|
||||
signals:
|
||||
void isSearchingChanged();
|
||||
void searchProgressChanged();
|
||||
|
||||
protected:
|
||||
void onDeviceReplyReadyRead();
|
||||
void broadcast();
|
||||
void stopSearchDevice();
|
||||
void timerEvent(QTimerEvent *event);
|
||||
|
||||
private:
|
||||
std::vector<DeviceInfomation> m_devices;
|
||||
std::list<QUdpSocket *> m_udpSockets;
|
||||
QUdpSocket *m_broadcastSocket = nullptr;
|
||||
int m_timerId = -1;
|
||||
int m_retries = 0;
|
||||
};
|
||||
|
||||
#endif // DEVICELISTMODEL_H
|
113
DeviceView.qml
113
DeviceView.qml
@ -1,5 +1,6 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import AntiClipSettings
|
||||
|
||||
Item {
|
||||
@ -7,14 +8,13 @@ Item {
|
||||
property int dargWidth: 12
|
||||
property color openDoorAreaColor: "green"
|
||||
property var openDoorAreaPoints: []
|
||||
property bool openDoorAreaEnabled: false
|
||||
property int openDoorAreaWay: 0
|
||||
property color shieldedAreaColor: "yellow"
|
||||
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
|
||||
@ -36,7 +36,13 @@ Item {
|
||||
onPaint: {
|
||||
var ctx = canvas.getContext("2d")
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||
if (openDoorAreaEnabled &&(openDoorAreaPoints.length > 0)) {
|
||||
if(openDoorAreaWay == DeviceConnection.FullArea){
|
||||
ctx.strokeStyle = openDoorAreaColor
|
||||
ctx.lineWidth = 8
|
||||
ctx.strokeRect(0,0, canvas.width,
|
||||
canvas.height)
|
||||
|
||||
} else if ((openDoorAreaWay>=DeviceConnection.Quadrangle) &&(openDoorAreaPoints.length > 0)) {
|
||||
ctx.strokeStyle = openDoorAreaColor
|
||||
ctx.lineWidth = 2
|
||||
|
||||
@ -69,7 +75,8 @@ Item {
|
||||
ctx.stroke()
|
||||
}
|
||||
if (shieldedAreaEnabled &&(shieldedAreaPoints.length > 0)) {
|
||||
ctx.strokeStyle = "green"
|
||||
ctx.lineWidth = 2
|
||||
ctx.strokeStyle = shieldedAreaColor
|
||||
let point0 = scaledPoint(shieldedAreaPoints[0],
|
||||
width, height)
|
||||
let point1 = scaledPoint(shieldedAreaPoints[1],
|
||||
@ -88,12 +95,12 @@ Item {
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
visible: openDoorAreaEnabled
|
||||
visible: openDoorAreaWay>=DeviceConnection.Quadrangle
|
||||
model: openDoorAreaPoints
|
||||
delegate: Rectangle {
|
||||
width: dargWidth
|
||||
height: dargWidth
|
||||
visible: openDoorAreaEnabled
|
||||
visible: openDoorAreaWay>=DeviceConnection.Quadrangle
|
||||
color: openDoorAreaColor
|
||||
x: scaledPoint(modelData, canvas.width,
|
||||
canvas.height).x - width / 2
|
||||
@ -110,7 +117,7 @@ Item {
|
||||
width: dargWidth
|
||||
height: dargWidth
|
||||
visible: shieldedAreaEnabled
|
||||
color: "green"
|
||||
color: shieldedAreaColor
|
||||
x: scaledPoint(modelData, canvas.width,
|
||||
canvas.height).x - width / 2
|
||||
y: scaledPoint(modelData, canvas.width,
|
||||
@ -140,7 +147,7 @@ Item {
|
||||
property int draggedShieldedAreaPointIndex: -1
|
||||
property int draggedAntiAreaPointIndex: -1
|
||||
onPressed: mouse => {
|
||||
if(openDoorAreaEnabled){
|
||||
if(openDoorAreaWay == DeviceConnection.Quadrangle){
|
||||
for (var i = 0; i < openDoorAreaPoints.length; i++) {
|
||||
let point = scaledPoint(
|
||||
openDoorAreaPoints[i], canvas.width,
|
||||
@ -226,38 +233,91 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
Row {
|
||||
Grid {
|
||||
id: controlBar
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
Switch {
|
||||
text: "开门区域"
|
||||
checked: openDoorAreaEnabled
|
||||
onToggled: App.currentOpenDoorAreaEnabled = checked
|
||||
columns: 2
|
||||
spacing: 10
|
||||
Text {text: qsTr("开门区域: ")}
|
||||
Row {
|
||||
RadioButton {
|
||||
text: "关闭"
|
||||
checked: App.currentOpenDoorAreaWay ==DeviceConnection.Diabled
|
||||
onToggled:{
|
||||
App.currentOpenDoorAreaWay =DeviceConnection.Diabled
|
||||
}
|
||||
Switch {
|
||||
text: "防夹区域"
|
||||
checked: antiClipAreaEnabled
|
||||
onToggled: App.currentAntiClipAreaEnabled = checked
|
||||
}
|
||||
Switch {
|
||||
text: "屏蔽区域"
|
||||
RadioButton {
|
||||
text: "全区域"
|
||||
checked: App.currentOpenDoorAreaWay ==DeviceConnection.FullArea
|
||||
onToggled:{
|
||||
App.currentOpenDoorAreaWay =DeviceConnection.FullArea
|
||||
}
|
||||
}
|
||||
RadioButton {
|
||||
text: "四边形"
|
||||
checked: App.currentOpenDoorAreaWay ==DeviceConnection.Quadrangle
|
||||
onToggled:{
|
||||
App.currentOpenDoorAreaWay =DeviceConnection.Quadrangle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Text {text: qsTr("防夹区域: ")}
|
||||
Row {
|
||||
RadioButton {
|
||||
text: "关闭"
|
||||
checked: !App.currentAntiClipAreaEnabled
|
||||
onToggled: {
|
||||
App.currentAntiClipAreaEnabled=false
|
||||
}
|
||||
|
||||
}
|
||||
RadioButton {
|
||||
text: "四边形"
|
||||
checked: App.currentAntiClipAreaEnabled
|
||||
onToggled: {
|
||||
App.currentAntiClipAreaEnabled=true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Text {text: qsTr("屏蔽区域: ")}
|
||||
Row {
|
||||
id: shieldedRow
|
||||
RadioButton {
|
||||
checked: !shieldedAreaEnabled
|
||||
text: "关闭"
|
||||
onToggled: {
|
||||
App.currentShieldedAreaEnabled = false
|
||||
}
|
||||
}
|
||||
RadioButton {
|
||||
checked: shieldedAreaEnabled
|
||||
onToggled: App.currentShieldedAreaEnabled = checked
|
||||
text: "开启"
|
||||
onToggled: {
|
||||
App.currentShieldedAreaEnabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 转换为显示画点
|
||||
function scaledPoint(point, width, height) {
|
||||
let x = point.x * width / 640
|
||||
let y = point.y * height / 360
|
||||
let x = point.x * width / App.DeviceWidth
|
||||
let y = point.y * height / App.DeviceHeight
|
||||
return Qt.point(x, y)
|
||||
}
|
||||
|
||||
// 转换为设备画点(640x360)
|
||||
function standardPoint(point, width, height) {
|
||||
let x = point.x * 640 / width
|
||||
let y = point.y * 360 / height
|
||||
let x = point.x * App.DeviceWidth / width
|
||||
let y = point.y * App.DeviceHeight / height
|
||||
return Qt.point(x, y)
|
||||
}
|
||||
|
||||
@ -269,6 +329,7 @@ Item {
|
||||
}
|
||||
function onCurrentOpenDoorAreaPointsChanged() {
|
||||
canvas.requestPaint()
|
||||
repeater.model = openDoorAreaPoints
|
||||
}
|
||||
function onCurrentShieldedAreaPointsChanged() {
|
||||
canvas.requestPaint()
|
||||
@ -276,7 +337,7 @@ Item {
|
||||
function onCurrentAntiClipAreaPointsChanged() {
|
||||
canvas.requestPaint()
|
||||
}
|
||||
function onCurrentOpenDoorAreaEnabledChanged(){
|
||||
function onCurrentOpenDoorAreaWayChanged(){
|
||||
canvas.requestPaint()
|
||||
}
|
||||
function onCurrentShieldedAreaEnabledChanged(){
|
||||
|
81
Main.qml
81
Main.qml
@ -4,8 +4,8 @@ import QtQuick.Layouts
|
||||
import AntiClipSettings
|
||||
|
||||
ApplicationWindow {
|
||||
width: 680
|
||||
height: 480
|
||||
width: 1000
|
||||
height: 640
|
||||
visible: true
|
||||
title: qsTr("Hello World")
|
||||
|
||||
@ -14,29 +14,73 @@ ApplicationWindow {
|
||||
anchors.fill: parent
|
||||
Button {
|
||||
text: "搜索设备"
|
||||
onClicked: {
|
||||
deviceList.currentIndex = -1
|
||||
App.devices.startSearchDevice()
|
||||
}
|
||||
Button {
|
||||
text: "连接"
|
||||
onClicked: App.open()
|
||||
}
|
||||
Button {
|
||||
text: "开始"
|
||||
onClicked: App.start()
|
||||
Row {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
Text {
|
||||
text: qsTr("当前设备版本号: ")
|
||||
}
|
||||
Text {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
text: qsTr("当前设备版本号: RD_T009_V02R001B001")
|
||||
}
|
||||
id: deviceVersion
|
||||
text: qsTr("RD_T009_V02R001B001")
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: deviceList
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
width: 250
|
||||
color: "red"
|
||||
width: 420
|
||||
clip: true
|
||||
model: App.devices
|
||||
delegate: Rectangle {
|
||||
width: deviceList.width
|
||||
height: 40
|
||||
color: ListView.isCurrentItem ? "#aaddff" : (index % 2 == 0 ? "#ffffff" : "#eeeeee")
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
Text {
|
||||
text: deviceId
|
||||
}
|
||||
Item {}
|
||||
Text {
|
||||
text: ip
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
deviceList.currentIndex = index
|
||||
|
||||
}
|
||||
onDoubleClicked: {
|
||||
networkPopup.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
onCurrentIndexChanged: {
|
||||
deviceVersion.text = App.devices.get(deviceList.currentIndex).softwareVersion;
|
||||
App.connectToDevice(App.devices.get(deviceList.currentIndex).ip)
|
||||
}
|
||||
ProgressBar {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
visible: App.devices.isSearching
|
||||
from: 0
|
||||
to: 100
|
||||
value: App.devices.searchProgress
|
||||
height: 25
|
||||
}
|
||||
}
|
||||
|
||||
DeviceView {
|
||||
@ -44,7 +88,7 @@ ApplicationWindow {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: deviceList.right
|
||||
anchors.right: parent.right
|
||||
openDoorAreaEnabled: App.currentOpenDoorAreaEnabled
|
||||
openDoorAreaWay: App.currentOpenDoorAreaWay
|
||||
openDoorAreaPoints: App.currentOpenDoorAreaPoints
|
||||
shieldedAreaEnabled: App.currentShieldedAreaEnabled
|
||||
shieldedAreaPoints: App.currentShieldedAreaPoints
|
||||
@ -52,6 +96,13 @@ ApplicationWindow {
|
||||
antiClipAreaPoints: App.currentAntiClipAreaPoints
|
||||
}
|
||||
|
||||
NetworkSettingPopup {
|
||||
id: networkPopup
|
||||
visible: false
|
||||
width: 500
|
||||
height: 240
|
||||
}
|
||||
|
||||
footer: RowLayout {
|
||||
width: parent.width
|
||||
Item {}
|
||||
|
117
NetworkSettingPopup.qml
Normal file
117
NetworkSettingPopup.qml
Normal file
@ -0,0 +1,117 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import AntiClipSettings
|
||||
|
||||
Popup {
|
||||
id: root
|
||||
parent: Overlay.overlay
|
||||
anchors.centerIn: Overlay.overlay
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
color: "white"
|
||||
border.color: "lightgray"
|
||||
radius: 10
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
spacing: 10
|
||||
padding: 20
|
||||
|
||||
Row {
|
||||
spacing: 10
|
||||
|
||||
Text {
|
||||
text: "模式"
|
||||
font.pointSize: 14
|
||||
width: 100
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
id: dhcpMode
|
||||
text: "DHCP"
|
||||
checked: App.currentNetworkInfomation.dhcp
|
||||
}
|
||||
|
||||
RadioButton {
|
||||
id: staticMode
|
||||
text: "静态IP"
|
||||
checked: !App.currentNetworkInfomation.dhcp
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: 5
|
||||
|
||||
Text {
|
||||
text: "设备IP"
|
||||
font.pointSize: 14
|
||||
width: 100
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: ipInput
|
||||
width: 350
|
||||
height: 30
|
||||
text: App.currentNetworkInfomation.ip
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: 5
|
||||
Text {
|
||||
width: 100
|
||||
text: "子网掩码"
|
||||
font.pointSize: 14
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: netmaskInput
|
||||
width: 350
|
||||
height: 30
|
||||
text: App.currentNetworkInfomation.netmask
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: 5
|
||||
|
||||
Row {
|
||||
spacing: 5
|
||||
|
||||
Text {
|
||||
text: "设备网关"
|
||||
font.pointSize: 14
|
||||
width: 100
|
||||
}
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: gatewayInput
|
||||
width: 350
|
||||
height: 30
|
||||
text: App.currentNetworkInfomation.gateway
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: 20
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Button {
|
||||
text: "保存"
|
||||
onClicked: {
|
||||
App.updateNetworkInfomation(dhcpMode.checked,ipInput.text,netmaskInput.text,gatewayInput.text);
|
||||
networkPopup.close()
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "取消"
|
||||
onClicked: root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user