初步实现网络修改。
This commit is contained in:
parent
0f24d95eee
commit
f59645700a
109
Application.cpp
109
Application.cpp
@ -1,7 +1,6 @@
|
|||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "BoostLog.h"
|
#include "BoostLog.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "DeviceConnection.h"
|
|
||||||
#include "H264Palyer.h"
|
#include "H264Palyer.h"
|
||||||
#include "VideoFrameProvider.h"
|
#include "VideoFrameProvider.h"
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
@ -10,7 +9,7 @@
|
|||||||
|
|
||||||
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>()), m_devices(new DeviceListModel(this)) {
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setPointSize(16);
|
font.setPointSize(16);
|
||||||
m_app->setFont(font);
|
m_app->setFont(font);
|
||||||
@ -19,19 +18,29 @@ Application::Application(int &argc, char **argv)
|
|||||||
m_player->open();
|
m_player->open();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::currentOpenDoorAreaEnabled() const {
|
DeviceConnection::AreaWay Application::currentOpenDoorAreaWay() const {
|
||||||
return m_currentOpenDoorAreaEnabled;
|
return m_currentOpenDoorAreaWay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setCurrentOpenDoorAreaEnabled(bool enabled) {
|
void Application::setCurrentOpenDoorAreaWay(DeviceConnection::AreaWay way) {
|
||||||
if (m_currentOpenDoorAreaEnabled != enabled) {
|
if (m_currentOpenDoorAreaWay == way) return;
|
||||||
m_currentOpenDoorAreaEnabled = enabled;
|
m_currentOpenDoorAreaWay = way;
|
||||||
emit currentOpenDoorAreaEnabledChanged();
|
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) {
|
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 {
|
QList<QPointF> Application::currentOpenDoorAreaPoints() const {
|
||||||
@ -45,6 +54,10 @@ void Application::setCurrentOpenDoorAreaPoints(const QList<QPointF> &points) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkInfomation Application::currentNetworkInfomation() const {
|
||||||
|
return m_currentNetworkInfomation;
|
||||||
|
}
|
||||||
|
|
||||||
bool Application::currentShieldedAreaEnabled() const {
|
bool Application::currentShieldedAreaEnabled() const {
|
||||||
return m_currentShieldedAreaEnabled;
|
return m_currentShieldedAreaEnabled;
|
||||||
}
|
}
|
||||||
@ -53,6 +66,13 @@ void Application::setCurrentShieldedAreaEnabled(bool enabled) {
|
|||||||
if (m_currentShieldedAreaEnabled != enabled) {
|
if (m_currentShieldedAreaEnabled != enabled) {
|
||||||
m_currentShieldedAreaEnabled = enabled;
|
m_currentShieldedAreaEnabled = enabled;
|
||||||
emit currentShieldedAreaEnabledChanged();
|
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) {
|
if (m_device != nullptr) {
|
||||||
m_device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, m_currentShieldedAreaPoints);
|
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) {
|
void Application::updateOpenDoorAreaPoints(const QList<QPointF> &points) {
|
||||||
LOG(info) << "updateOpenDoorAreaPoints: " << points.size();
|
if (m_device != nullptr) {
|
||||||
m_device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaEnabled, points);
|
m_device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaWay, points);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::updateAntiClipAreaPoints(const QList<QPointF> &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);
|
m_device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, points);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onDeviceOpenDoorArea(bool enabled, const QList<QPointF> &points) {
|
void Application::updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask,
|
||||||
setCurrentOpenDoorAreaEnabled(enabled);
|
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);
|
setCurrentOpenDoorAreaPoints(points);
|
||||||
LOG(info) << "onDeviceOpenDoorAreaPoints: " << points.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::onDeviceShieldedArea(bool enabled, const QList<QPointF> &points) {
|
void Application::onDeviceShieldedArea(bool enabled, const QList<QPointF> &points) {
|
||||||
@ -125,6 +175,11 @@ void Application::onDeviceAntiClipArea(bool enabled, const QList<QPointF> &point
|
|||||||
setCurrentAntiClipAreaPoints(points);
|
setCurrentAntiClipAreaPoints(points);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::onDeviceNetworkInfomation(const NetworkInfomation &info) {
|
||||||
|
m_currentNetworkInfomation = info;
|
||||||
|
emit currentNetworkInfomationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
int Application::exec() {
|
int Application::exec() {
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
engine.addImageProvider("videoframe", m_videoFrameProvider);
|
engine.addImageProvider("videoframe", m_videoFrameProvider);
|
||||||
@ -135,28 +190,6 @@ int Application::exec() {
|
|||||||
return m_app->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 *Application::create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) {
|
||||||
Application *ret = nullptr;
|
Application *ret = nullptr;
|
||||||
auto app = Amass::Singleton<Application>::instance();
|
auto app = Amass::Singleton<Application>::instance();
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
#ifndef APPLICATION_H
|
#ifndef APPLICATION_H
|
||||||
#define APPLICATION_H
|
#define APPLICATION_H
|
||||||
|
|
||||||
|
#include "DataStructure.h"
|
||||||
|
#include "DeviceConnection.h"
|
||||||
|
#include "DeviceListModel.h"
|
||||||
#include "Singleton.h"
|
#include "Singleton.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
|
||||||
class QGuiApplication;
|
class QGuiApplication;
|
||||||
class DeviceConnection;
|
|
||||||
class VideoFrameProvider;
|
class VideoFrameProvider;
|
||||||
class H264Palyer;
|
class H264Palyer;
|
||||||
|
|
||||||
@ -16,8 +18,10 @@ class Application : public QObject {
|
|||||||
QML_NAMED_ELEMENT(App)
|
QML_NAMED_ELEMENT(App)
|
||||||
QML_SINGLETON
|
QML_SINGLETON
|
||||||
Q_PROPERTY(int DeviceWidth MEMBER DeviceWidth CONSTANT FINAL)
|
Q_PROPERTY(int DeviceWidth MEMBER DeviceWidth CONSTANT FINAL)
|
||||||
Q_PROPERTY(bool currentOpenDoorAreaEnabled READ currentOpenDoorAreaEnabled WRITE setCurrentOpenDoorAreaEnabled
|
Q_PROPERTY(int DeviceHeight MEMBER DeviceHeight CONSTANT FINAL)
|
||||||
NOTIFY currentOpenDoorAreaEnabledChanged)
|
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
|
Q_PROPERTY(QList<QPointF> currentOpenDoorAreaPoints READ currentOpenDoorAreaPoints WRITE
|
||||||
setCurrentOpenDoorAreaPoints NOTIFY currentOpenDoorAreaPointsChanged)
|
setCurrentOpenDoorAreaPoints NOTIFY currentOpenDoorAreaPointsChanged)
|
||||||
Q_PROPERTY(bool currentShieldedAreaEnabled READ currentShieldedAreaEnabled WRITE setCurrentShieldedAreaEnabled
|
Q_PROPERTY(bool currentShieldedAreaEnabled READ currentShieldedAreaEnabled WRITE setCurrentShieldedAreaEnabled
|
||||||
@ -28,15 +32,22 @@ class Application : public QObject {
|
|||||||
NOTIFY currentAntiClipAreaEnabledChanged)
|
NOTIFY currentAntiClipAreaEnabledChanged)
|
||||||
Q_PROPERTY(QList<QPointF> currentAntiClipAreaPoints READ currentAntiClipAreaPoints WRITE
|
Q_PROPERTY(QList<QPointF> currentAntiClipAreaPoints READ currentAntiClipAreaPoints WRITE
|
||||||
setCurrentAntiClipAreaPoints NOTIFY currentAntiClipAreaPointsChanged)
|
setCurrentAntiClipAreaPoints NOTIFY currentAntiClipAreaPointsChanged)
|
||||||
|
Q_PROPERTY(
|
||||||
|
NetworkInfomation currentNetworkInfomation READ currentNetworkInfomation NOTIFY currentNetworkInfomationChanged)
|
||||||
friend class Amass::Singleton<Application>;
|
friend class Amass::Singleton<Application>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr static int DeviceWidth = 640;
|
constexpr static int DeviceWidth = 640;
|
||||||
bool currentOpenDoorAreaEnabled() const;
|
constexpr static int DeviceHeight = 360;
|
||||||
void setCurrentOpenDoorAreaEnabled(bool enabled);
|
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;
|
QList<QPointF> currentOpenDoorAreaPoints() const;
|
||||||
void setCurrentOpenDoorAreaPoints(const QList<QPointF> &points);
|
void setCurrentOpenDoorAreaPoints(const QList<QPointF> &points);
|
||||||
|
|
||||||
|
NetworkInfomation currentNetworkInfomation() const;
|
||||||
|
|
||||||
bool currentShieldedAreaEnabled() const;
|
bool currentShieldedAreaEnabled() const;
|
||||||
void setCurrentShieldedAreaEnabled(bool enabled);
|
void setCurrentShieldedAreaEnabled(bool enabled);
|
||||||
QList<QPointF> currentShieldedAreaPoints() const;
|
QList<QPointF> currentShieldedAreaPoints() const;
|
||||||
@ -50,10 +61,11 @@ public:
|
|||||||
Q_INVOKABLE void updateOpenDoorAreaPoints(const QList<QPointF> &points);
|
Q_INVOKABLE void updateOpenDoorAreaPoints(const QList<QPointF> &points);
|
||||||
Q_INVOKABLE void updateAntiClipAreaPoints(const QList<QPointF> &points);
|
Q_INVOKABLE void updateAntiClipAreaPoints(const QList<QPointF> &points);
|
||||||
Q_INVOKABLE void updateShieldedAreaPoints(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();
|
int exec();
|
||||||
Q_INVOKABLE void open();
|
|
||||||
Q_INVOKABLE void start();
|
|
||||||
static Application *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine);
|
static Application *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@ -61,28 +73,32 @@ signals:
|
|||||||
void currentOpenDoorAreaPointsChanged();
|
void currentOpenDoorAreaPointsChanged();
|
||||||
void currentShieldedAreaPointsChanged();
|
void currentShieldedAreaPointsChanged();
|
||||||
void currentAntiClipAreaPointsChanged();
|
void currentAntiClipAreaPointsChanged();
|
||||||
void currentOpenDoorAreaEnabledChanged();
|
void currentOpenDoorAreaWayChanged();
|
||||||
void currentShieldedAreaEnabledChanged();
|
void currentShieldedAreaEnabledChanged();
|
||||||
void currentAntiClipAreaEnabledChanged();
|
void currentAntiClipAreaEnabledChanged();
|
||||||
|
void currentNetworkInfomationChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Application(int &argc, char **argv);
|
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 onDeviceShieldedArea(bool enabled, const QList<QPointF> &points);
|
||||||
void onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points);
|
void onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points);
|
||||||
|
void onDeviceNetworkInfomation(const NetworkInfomation &info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<QGuiApplication> m_app;
|
std::shared_ptr<QGuiApplication> m_app;
|
||||||
VideoFrameProvider *m_videoFrameProvider = nullptr;
|
VideoFrameProvider *m_videoFrameProvider = nullptr;
|
||||||
std::shared_ptr<H264Palyer> m_player;
|
std::shared_ptr<H264Palyer> m_player;
|
||||||
DeviceConnection *m_device = nullptr;
|
DeviceConnection *m_device = nullptr;
|
||||||
|
DeviceListModel *m_devices = nullptr;
|
||||||
|
|
||||||
bool m_currentOpenDoorAreaEnabled = false;
|
DeviceConnection::AreaWay m_currentOpenDoorAreaWay = DeviceConnection::Diabled;
|
||||||
QList<QPointF> m_currentOpenDoorAreaPoints;
|
QList<QPointF> m_currentOpenDoorAreaPoints;
|
||||||
bool m_currentShieldedAreaEnabled = false;
|
bool m_currentShieldedAreaEnabled = false;
|
||||||
QList<QPointF> m_currentShieldedAreaPoints;
|
QList<QPointF> m_currentShieldedAreaPoints;
|
||||||
bool m_currentAntiClipAreaEnabled = false;
|
bool m_currentAntiClipAreaEnabled = false;
|
||||||
QList<QPointF> m_currentAntiClipAreaPoints;
|
QList<QPointF> m_currentAntiClipAreaPoints;
|
||||||
|
NetworkInfomation m_currentNetworkInfomation;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // APPLICATION_H
|
#endif // APPLICATION_H
|
||||||
|
@ -9,8 +9,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||||||
set(Projects_ROOT E:/Projects)
|
set(Projects_ROOT E:/Projects)
|
||||||
set(Libraries_ROOT ${Projects_ROOT}/Libraries)
|
set(Libraries_ROOT ${Projects_ROOT}/Libraries)
|
||||||
|
|
||||||
set(BOOST_ROOT ${Libraries_ROOT}/boost_1_85_0_msvc2022_64bit)
|
set(BOOST_ROOT ${Libraries_ROOT}/boost_1_86_0_msvc2022_64bit)
|
||||||
set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include/boost-1_85)
|
set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include/boost-1_86)
|
||||||
option(Boost_USE_STATIC_LIBS OFF)
|
option(Boost_USE_STATIC_LIBS OFF)
|
||||||
add_compile_definitions(
|
add_compile_definitions(
|
||||||
BOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WIN10
|
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)
|
set(FFmpeg_LIB_DIR ${FFmpeg_ROOT}/lib)
|
||||||
|
|
||||||
find_package(Boost REQUIRED COMPONENTS json)
|
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)
|
qt_standard_project_setup(REQUIRES 6.5)
|
||||||
|
|
||||||
@ -36,7 +36,9 @@ qt_add_executable(AntiClipSettings
|
|||||||
AntiClipSettings.rc
|
AntiClipSettings.rc
|
||||||
main.cpp
|
main.cpp
|
||||||
Application.h Application.cpp
|
Application.h Application.cpp
|
||||||
|
DataStructure.h
|
||||||
DeviceConnection.h DeviceConnection.cpp
|
DeviceConnection.h DeviceConnection.cpp
|
||||||
|
DeviceListModel.h DeviceListModel.cpp
|
||||||
H264Palyer.h H264Palyer.cpp
|
H264Palyer.h H264Palyer.cpp
|
||||||
VideoFrameProvider.h VideoFrameProvider.cpp
|
VideoFrameProvider.h VideoFrameProvider.cpp
|
||||||
)
|
)
|
||||||
@ -46,6 +48,7 @@ qt_add_qml_module(AntiClipSettings
|
|||||||
QML_FILES
|
QML_FILES
|
||||||
Main.qml
|
Main.qml
|
||||||
DeviceView.qml
|
DeviceView.qml
|
||||||
|
NetworkSettingPopup.qml
|
||||||
)
|
)
|
||||||
|
|
||||||
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
|
# 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
|
target_link_libraries(AntiClipSettings
|
||||||
PRIVATE Qt6::Qml
|
PRIVATE Qt6::Qml
|
||||||
PRIVATE Qt6::Quick
|
PRIVATE Qt6::Quick
|
||||||
|
PRIVATE Qt6::Network
|
||||||
PRIVATE Boost::json
|
PRIVATE Boost::json
|
||||||
PRIVATE avcodec
|
PRIVATE avcodec
|
||||||
PRIVATE swscale
|
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 "DeviceConnection.h"
|
||||||
#include "BoostLog.h"
|
#include "BoostLog.h"
|
||||||
#include <QPointF>
|
#include <QPointF>
|
||||||
#include <QTcpSocket>
|
|
||||||
#include <WinSock2.h>
|
#include <WinSock2.h>
|
||||||
#include <boost/json/object.hpp>
|
#include <boost/json/object.hpp>
|
||||||
#include <boost/json/parse.hpp>
|
#include <boost/json/parse.hpp>
|
||||||
@ -10,7 +9,7 @@
|
|||||||
DeviceConnection::DeviceConnection(QObject *parent) : QObject{parent} {
|
DeviceConnection::DeviceConnection(QObject *parent) : QObject{parent} {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceConnection::connect() {
|
void DeviceConnection::connect(const QString &address) {
|
||||||
m_commandSocket = new QTcpSocket(this);
|
m_commandSocket = new QTcpSocket(this);
|
||||||
m_h264Socket = 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_h264Socket, &QTcpSocket::readyRead, this, &DeviceConnection::onH264ReadyRead);
|
||||||
QObject::connect(m_commandSocket, &QTcpSocket::readyRead, this, &DeviceConnection::onCommandReadyRead);
|
QObject::connect(m_commandSocket, &QTcpSocket::readyRead, this, &DeviceConnection::onCommandReadyRead);
|
||||||
|
|
||||||
m_commandSocket->connectToHost("192.168.10.2", 8000);
|
m_commandSocket->connectToHost(address, 8000);
|
||||||
m_h264Socket->connectToHost("192.168.10.2", 8000);
|
m_h264Socket->connectToHost(address, 8000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceConnection::start() {
|
void DeviceConnection::start() {
|
||||||
@ -53,13 +52,19 @@ void DeviceConnection::requestOpenDoorArea() {
|
|||||||
m_requests.push(task);
|
m_requests.push(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceConnection::updateOpenDoorAreaPoints(bool enabled, const QList<QPointF> &points) {
|
void DeviceConnection::updateOpenDoorAreaPoints(AreaWay way, const QList<QPointF> &points) {
|
||||||
auto task = [this, enabled, points]() {
|
auto task = [this, way, points]() {
|
||||||
boost::json::object request;
|
boost::json::object request;
|
||||||
request["func"] = "a03opendoor1_setdata";
|
request["func"] = "a03opendoor1_setdata";
|
||||||
request["deviceid"] = "0";
|
request["deviceid"] = "0";
|
||||||
boost::json::object data;
|
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;
|
boost::json::array pointArray;
|
||||||
for (auto &p : points) {
|
for (auto &p : points) {
|
||||||
boost::json::object point;
|
boost::json::object point;
|
||||||
@ -186,6 +191,46 @@ void DeviceConnection::requestResolution(Resolution resolution) {
|
|||||||
m_requests.push(task);
|
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) {
|
void DeviceConnection::handleCommand(const std::string_view &replyText) {
|
||||||
boost::system::error_code error;
|
boost::system::error_code error;
|
||||||
auto replyValue = boost::json::parse(replyText, 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());
|
point.setY(obj.at("y").as_double());
|
||||||
points.push_back(point);
|
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") {
|
} else if (function == "a03opendoor4_getdata") {
|
||||||
auto &data = reply.at("data").as_object();
|
auto &data = reply.at("data").as_object();
|
||||||
auto &value = data.at("value").as_string();
|
auto &value = data.at("value").as_string();
|
||||||
@ -234,6 +285,14 @@ void DeviceConnection::handleCommand(const std::string_view &replyText) {
|
|||||||
points.push_back(point);
|
points.push_back(point);
|
||||||
}
|
}
|
||||||
emit currentAntiClipAreaChanged(value == "1", points);
|
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();
|
requestOpenDoorArea();
|
||||||
requestShieldedArea();
|
requestShieldedArea();
|
||||||
requestAntiClipArea();
|
requestAntiClipArea();
|
||||||
|
requestNetworkInfomation();
|
||||||
|
} else if (socket == m_h264Socket) {
|
||||||
|
start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
#ifndef DEVICECONNECTION_H
|
#ifndef DEVICECONNECTION_H
|
||||||
#define DEVICECONNECTION_H
|
#define DEVICECONNECTION_H
|
||||||
|
|
||||||
|
#include "DataStructure.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
#include <QTcpSocket>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
class QTcpSocket;
|
|
||||||
|
class NetworkInfomation;
|
||||||
|
|
||||||
class DeviceConnection : public QObject {
|
class DeviceConnection : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
QML_ELEMENT
|
QML_ELEMENT
|
||||||
QML_UNCREATABLE("Only used in C++...")
|
QML_UNCREATABLE("Only created in C++...")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Resolution {
|
enum Resolution {
|
||||||
@ -19,33 +22,37 @@ public:
|
|||||||
};
|
};
|
||||||
enum AreaWay {
|
enum AreaWay {
|
||||||
Diabled = 0,
|
Diabled = 0,
|
||||||
FullScreen,
|
FullArea,
|
||||||
Quadrangle, // 四边形
|
Quadrangle, // 四边形
|
||||||
};
|
};
|
||||||
Q_ENUM(AreaWay)
|
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(const QString &address);
|
||||||
void start();
|
void start();
|
||||||
void requestOpenDoorArea();
|
void requestOpenDoorArea();
|
||||||
void updateOpenDoorAreaPoints(bool enabled, const QList<QPointF> &points);
|
void updateOpenDoorAreaPoints(AreaWay way, const QList<QPointF> &points);
|
||||||
void requestShieldedArea();
|
void requestShieldedArea();
|
||||||
void updateShieldedAreaPoints(bool enabled, const QList<QPointF> &points);
|
void updateShieldedAreaPoints(bool enabled, const QList<QPointF> &points);
|
||||||
void requestAntiClipArea();
|
void requestAntiClipArea();
|
||||||
void updateAntiClipAreaPoints(bool enabled, const QList<QPointF> &points);
|
void updateAntiClipAreaPoints(bool enabled, const QList<QPointF> &points);
|
||||||
void requestResolution(Resolution resolution);
|
void requestResolution(Resolution resolution);
|
||||||
|
void requestNetworkInfomation();
|
||||||
|
void updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway);
|
||||||
|
|
||||||
signals:
|
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 currentShieldedAreaChanged(bool enabled, const QList<QPointF> &points);
|
||||||
void currentAntiClipAreaChanged(bool enabled, const QList<QPointF> &points);
|
void currentAntiClipAreaChanged(bool enabled, const QList<QPointF> &points);
|
||||||
|
void currentNetworkInfomationChanged(const NetworkInfomation &info);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onConnected();
|
void onConnected();
|
||||||
void onH264ReadyRead();
|
void onH264ReadyRead();
|
||||||
void onCommandReadyRead();
|
void onCommandReadyRead();
|
||||||
void handleCommand(const std::string_view &replyText);
|
void handleCommand(const std::string_view &replyText);
|
||||||
|
void onErrorOccurred(QAbstractSocket::SocketError socketError);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTcpSocket *m_commandSocket = nullptr;
|
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
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
import AntiClipSettings
|
import AntiClipSettings
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@ -7,14 +8,13 @@ Item {
|
|||||||
property int dargWidth: 12
|
property int dargWidth: 12
|
||||||
property color openDoorAreaColor: "green"
|
property color openDoorAreaColor: "green"
|
||||||
property var openDoorAreaPoints: []
|
property var openDoorAreaPoints: []
|
||||||
property bool openDoorAreaEnabled: false
|
property int openDoorAreaWay: 0
|
||||||
|
property color shieldedAreaColor: "yellow"
|
||||||
property var shieldedAreaPoints: []
|
property var shieldedAreaPoints: []
|
||||||
property bool shieldedAreaEnabled: false
|
property bool shieldedAreaEnabled: false
|
||||||
property color antiClipAreaColor: "blue"
|
property color antiClipAreaColor: "blue"
|
||||||
property var antiClipAreaPoints: []
|
property var antiClipAreaPoints: []
|
||||||
property bool antiClipAreaEnabled: false
|
property bool antiClipAreaEnabled: false
|
||||||
property var defaultShieldedAreaPoints: [Qt.point(6, 6), Qt.point(40, 60),
|
|
||||||
Qt.point(598, 6), Qt.point(633, 60)]
|
|
||||||
Item {
|
Item {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@ -36,7 +36,13 @@ 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 (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.strokeStyle = openDoorAreaColor
|
||||||
ctx.lineWidth = 2
|
ctx.lineWidth = 2
|
||||||
|
|
||||||
@ -69,7 +75,8 @@ Item {
|
|||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
}
|
}
|
||||||
if (shieldedAreaEnabled &&(shieldedAreaPoints.length > 0)) {
|
if (shieldedAreaEnabled &&(shieldedAreaPoints.length > 0)) {
|
||||||
ctx.strokeStyle = "green"
|
ctx.lineWidth = 2
|
||||||
|
ctx.strokeStyle = shieldedAreaColor
|
||||||
let point0 = scaledPoint(shieldedAreaPoints[0],
|
let point0 = scaledPoint(shieldedAreaPoints[0],
|
||||||
width, height)
|
width, height)
|
||||||
let point1 = scaledPoint(shieldedAreaPoints[1],
|
let point1 = scaledPoint(shieldedAreaPoints[1],
|
||||||
@ -88,12 +95,12 @@ Item {
|
|||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
visible: openDoorAreaEnabled
|
visible: openDoorAreaWay>=DeviceConnection.Quadrangle
|
||||||
model: openDoorAreaPoints
|
model: openDoorAreaPoints
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
width: dargWidth
|
width: dargWidth
|
||||||
height: dargWidth
|
height: dargWidth
|
||||||
visible: openDoorAreaEnabled
|
visible: openDoorAreaWay>=DeviceConnection.Quadrangle
|
||||||
color: openDoorAreaColor
|
color: openDoorAreaColor
|
||||||
x: scaledPoint(modelData, canvas.width,
|
x: scaledPoint(modelData, canvas.width,
|
||||||
canvas.height).x - width / 2
|
canvas.height).x - width / 2
|
||||||
@ -110,7 +117,7 @@ Item {
|
|||||||
width: dargWidth
|
width: dargWidth
|
||||||
height: dargWidth
|
height: dargWidth
|
||||||
visible: shieldedAreaEnabled
|
visible: shieldedAreaEnabled
|
||||||
color: "green"
|
color: shieldedAreaColor
|
||||||
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,
|
||||||
@ -140,7 +147,7 @@ Item {
|
|||||||
property int draggedShieldedAreaPointIndex: -1
|
property int draggedShieldedAreaPointIndex: -1
|
||||||
property int draggedAntiAreaPointIndex: -1
|
property int draggedAntiAreaPointIndex: -1
|
||||||
onPressed: mouse => {
|
onPressed: mouse => {
|
||||||
if(openDoorAreaEnabled){
|
if(openDoorAreaWay == DeviceConnection.Quadrangle){
|
||||||
for (var i = 0; i < openDoorAreaPoints.length; i++) {
|
for (var i = 0; i < openDoorAreaPoints.length; i++) {
|
||||||
let point = scaledPoint(
|
let point = scaledPoint(
|
||||||
openDoorAreaPoints[i], canvas.width,
|
openDoorAreaPoints[i], canvas.width,
|
||||||
@ -226,38 +233,91 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Row {
|
Grid {
|
||||||
id: controlBar
|
id: controlBar
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
Switch {
|
columns: 2
|
||||||
text: "开门区域"
|
spacing: 10
|
||||||
checked: openDoorAreaEnabled
|
Text {text: qsTr("开门区域: ")}
|
||||||
onToggled: App.currentOpenDoorAreaEnabled = checked
|
Row {
|
||||||
|
RadioButton {
|
||||||
|
text: "关闭"
|
||||||
|
checked: App.currentOpenDoorAreaWay ==DeviceConnection.Diabled
|
||||||
|
onToggled:{
|
||||||
|
App.currentOpenDoorAreaWay =DeviceConnection.Diabled
|
||||||
}
|
}
|
||||||
Switch {
|
|
||||||
text: "防夹区域"
|
|
||||||
checked: antiClipAreaEnabled
|
|
||||||
onToggled: App.currentAntiClipAreaEnabled = checked
|
|
||||||
}
|
}
|
||||||
Switch {
|
RadioButton {
|
||||||
text: "屏蔽区域"
|
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
|
checked: shieldedAreaEnabled
|
||||||
onToggled: App.currentShieldedAreaEnabled = checked
|
text: "开启"
|
||||||
|
onToggled: {
|
||||||
|
App.currentShieldedAreaEnabled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 转换为显示画点
|
// 转换为显示画点
|
||||||
function scaledPoint(point, width, height) {
|
function scaledPoint(point, width, height) {
|
||||||
let x = point.x * width / 640
|
let x = point.x * width / App.DeviceWidth
|
||||||
let y = point.y * height / 360
|
let y = point.y * height / App.DeviceHeight
|
||||||
return Qt.point(x, y)
|
return Qt.point(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转换为设备画点(640x360)
|
// 转换为设备画点(640x360)
|
||||||
function standardPoint(point, width, height) {
|
function standardPoint(point, width, height) {
|
||||||
let x = point.x * 640 / width
|
let x = point.x * App.DeviceWidth / width
|
||||||
let y = point.y * 360 / height
|
let y = point.y * App.DeviceHeight / height
|
||||||
return Qt.point(x, y)
|
return Qt.point(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,6 +329,7 @@ Item {
|
|||||||
}
|
}
|
||||||
function onCurrentOpenDoorAreaPointsChanged() {
|
function onCurrentOpenDoorAreaPointsChanged() {
|
||||||
canvas.requestPaint()
|
canvas.requestPaint()
|
||||||
|
repeater.model = openDoorAreaPoints
|
||||||
}
|
}
|
||||||
function onCurrentShieldedAreaPointsChanged() {
|
function onCurrentShieldedAreaPointsChanged() {
|
||||||
canvas.requestPaint()
|
canvas.requestPaint()
|
||||||
@ -276,7 +337,7 @@ Item {
|
|||||||
function onCurrentAntiClipAreaPointsChanged() {
|
function onCurrentAntiClipAreaPointsChanged() {
|
||||||
canvas.requestPaint()
|
canvas.requestPaint()
|
||||||
}
|
}
|
||||||
function onCurrentOpenDoorAreaEnabledChanged(){
|
function onCurrentOpenDoorAreaWayChanged(){
|
||||||
canvas.requestPaint()
|
canvas.requestPaint()
|
||||||
}
|
}
|
||||||
function onCurrentShieldedAreaEnabledChanged(){
|
function onCurrentShieldedAreaEnabledChanged(){
|
||||||
|
81
Main.qml
81
Main.qml
@ -4,8 +4,8 @@ import QtQuick.Layouts
|
|||||||
import AntiClipSettings
|
import AntiClipSettings
|
||||||
|
|
||||||
ApplicationWindow {
|
ApplicationWindow {
|
||||||
width: 680
|
width: 1000
|
||||||
height: 480
|
height: 640
|
||||||
visible: true
|
visible: true
|
||||||
title: qsTr("Hello World")
|
title: qsTr("Hello World")
|
||||||
|
|
||||||
@ -14,29 +14,73 @@ ApplicationWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
Button {
|
Button {
|
||||||
text: "搜索设备"
|
text: "搜索设备"
|
||||||
|
onClicked: {
|
||||||
|
deviceList.currentIndex = -1
|
||||||
|
App.devices.startSearchDevice()
|
||||||
}
|
}
|
||||||
Button {
|
|
||||||
text: "连接"
|
|
||||||
onClicked: App.open()
|
|
||||||
}
|
}
|
||||||
Button {
|
Row {
|
||||||
text: "开始"
|
Layout.alignment: Qt.AlignRight
|
||||||
onClicked: App.start()
|
Text {
|
||||||
|
text: qsTr("当前设备版本号: ")
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
Layout.alignment: Qt.AlignRight
|
id: deviceVersion
|
||||||
text: qsTr("当前设备版本号: RD_T009_V02R001B001")
|
text: qsTr("RD_T009_V02R001B001")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
id: deviceList
|
id: deviceList
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
width: 250
|
width: 420
|
||||||
color: "red"
|
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 {
|
DeviceView {
|
||||||
@ -44,7 +88,7 @@ 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
|
openDoorAreaWay: App.currentOpenDoorAreaWay
|
||||||
openDoorAreaPoints: App.currentOpenDoorAreaPoints
|
openDoorAreaPoints: App.currentOpenDoorAreaPoints
|
||||||
shieldedAreaEnabled: App.currentShieldedAreaEnabled
|
shieldedAreaEnabled: App.currentShieldedAreaEnabled
|
||||||
shieldedAreaPoints: App.currentShieldedAreaPoints
|
shieldedAreaPoints: App.currentShieldedAreaPoints
|
||||||
@ -52,6 +96,13 @@ ApplicationWindow {
|
|||||||
antiClipAreaPoints: App.currentAntiClipAreaPoints
|
antiClipAreaPoints: App.currentAntiClipAreaPoints
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkSettingPopup {
|
||||||
|
id: networkPopup
|
||||||
|
visible: false
|
||||||
|
width: 500
|
||||||
|
height: 240
|
||||||
|
}
|
||||||
|
|
||||||
footer: RowLayout {
|
footer: RowLayout {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
Item {}
|
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