Compare commits

..

No commits in common. "master" and "v1.6" have entirely different histories.
master ... v1.6

13 changed files with 73 additions and 621 deletions

View File

@ -12,7 +12,5 @@
<file>resources/prompt_delete.svg</file> <file>resources/prompt_delete.svg</file>
<file>resources/successfull.svg</file> <file>resources/successfull.svg</file>
<file>resources/warning.svg</file> <file>resources/warning.svg</file>
<file>qml/MessageBar.qml</file>
<file>qml/Object.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -127,24 +127,7 @@ void Application::setCurrentAntiClipAreaEnabled(bool enabled) {
emit currentAntiClipAreaEnabledChanged(); emit currentAntiClipAreaEnabledChanged();
if (!m_device.expired()) { if (!m_device.expired()) {
auto device = m_device.lock(); auto device = m_device.lock();
device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, m_currentAntiClipAreaPoints, device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, m_currentAntiClipAreaPoints);
m_currentAntiClipSensitivity);
}
}
}
int Application::currentAntiClipSensitivity() const {
return m_currentAntiClipSensitivity;
}
void Application::setCurrentAntiClipSensitivity(int sensitivity) {
if (m_currentAntiClipSensitivity != sensitivity) {
m_currentAntiClipSensitivity = sensitivity;
emit currentAntiClipSensitivityChanged();
if (!m_device.expired()) {
auto device = m_device.lock();
device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, m_currentAntiClipAreaPoints,
m_currentAntiClipSensitivity);
} }
} }
} }
@ -170,7 +153,7 @@ void Application::updateOpenDoorAreaPoints(const QList<QPointF> &points) {
void Application::updateAntiClipAreaPoints(const QList<QPointF> &points) { void Application::updateAntiClipAreaPoints(const QList<QPointF> &points) {
if (!m_device.expired()) { if (!m_device.expired()) {
auto device = m_device.lock(); auto device = m_device.lock();
device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, points, m_currentAntiClipSensitivity); device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, points);
} }
} }
@ -210,51 +193,6 @@ void Application::setCurrentDeviceRotation(int rotation) {
} }
} }
int Application::currentHelmetThreshold() const {
return m_currentHelmetThreshold;
}
void Application::setCurrentHelmetThreshold(int threshold) {
if (m_currentHelmetThreshold != threshold) {
m_currentHelmetThreshold = threshold;
emit currentHelmetThresholdChanged();
if (!m_device.expired()) {
auto device = m_device.lock();
device->updateDetectThreshold(m_currentHelmetThreshold, m_currentHeadThreshold, m_currentDetectFrameSize);
}
}
}
int Application::currentHeadThreshold() const {
return m_currentHeadThreshold;
}
void Application::setCurrentHeadThreshold(int threshold) {
if (m_currentHeadThreshold != threshold) {
m_currentHeadThreshold = threshold;
emit currentHeadThresholdChanged();
if (!m_device.expired()) {
auto device = m_device.lock();
device->updateDetectThreshold(m_currentHelmetThreshold, m_currentHeadThreshold, m_currentDetectFrameSize);
}
}
}
int Application::currentDetectFrameSize() const {
return m_currentDetectFrameSize;
}
void Application::setCurrentDetectFrameSize(int size) {
if (m_currentDetectFrameSize != size) {
m_currentDetectFrameSize = size;
emit currentDetectFrameSizeChanged();
if (!m_device.expired()) {
auto device = m_device.lock();
device->updateDetectThreshold(m_currentHelmetThreshold, m_currentHeadThreshold, m_currentDetectFrameSize);
}
}
}
void Application::updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway, void Application::updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway,
const QString &dns) { const QString &dns) {
if (!m_device.expired()) { if (!m_device.expired()) {
@ -276,8 +214,6 @@ void Application::connectToDevice(int index) {
disconnect(device.get(), &DeviceConnection::openDoorAreaChanged, this, &Application::onDeviceOpenDoorArea); disconnect(device.get(), &DeviceConnection::openDoorAreaChanged, this, &Application::onDeviceOpenDoorArea);
disconnect(device.get(), &DeviceConnection::shieldedAreaChanged, this, &Application::onDeviceShieldedArea); disconnect(device.get(), &DeviceConnection::shieldedAreaChanged, this, &Application::onDeviceShieldedArea);
disconnect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea); disconnect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
disconnect(device.get(), &DeviceConnection::detectThresholdChanged, this,
&Application::onDeviceDetectThresholdChanged);
disconnect(device.get(), &DeviceConnection::networkInfomationChanged, this, disconnect(device.get(), &DeviceConnection::networkInfomationChanged, this,
&Application::onDeviceNetworkInfomation); &Application::onDeviceNetworkInfomation);
disconnect(device.get(), &DeviceConnection::firmwareChanged, this, &Application::onDeviceFirmware); disconnect(device.get(), &DeviceConnection::firmwareChanged, this, &Application::onDeviceFirmware);
@ -302,8 +238,6 @@ void Application::connectToDevice(int index) {
connect(device.get(), &DeviceConnection::openDoorAreaChanged, this, &Application::onDeviceOpenDoorArea); connect(device.get(), &DeviceConnection::openDoorAreaChanged, this, &Application::onDeviceOpenDoorArea);
connect(device.get(), &DeviceConnection::shieldedAreaChanged, this, &Application::onDeviceShieldedArea); connect(device.get(), &DeviceConnection::shieldedAreaChanged, this, &Application::onDeviceShieldedArea);
connect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea); connect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
connect(device.get(), &DeviceConnection::detectThresholdChanged, this,
&Application::onDeviceDetectThresholdChanged);
connect(device.get(), &DeviceConnection::networkInfomationChanged, this, connect(device.get(), &DeviceConnection::networkInfomationChanged, this,
&Application::onDeviceNetworkInfomation); &Application::onDeviceNetworkInfomation);
connect(device.get(), &DeviceConnection::firmwareChanged, this, &Application::onDeviceFirmware); connect(device.get(), &DeviceConnection::firmwareChanged, this, &Application::onDeviceFirmware);
@ -326,15 +260,11 @@ void Application::connectToDevice(int index) {
m_currentShieldedAreaPoints = info.shieldedArea; m_currentShieldedAreaPoints = info.shieldedArea;
m_currentAntiClipAreaEnabled = info.antiClipAreaEnabled; m_currentAntiClipAreaEnabled = info.antiClipAreaEnabled;
m_currentAntiClipAreaPoints = info.antiClipArea; m_currentAntiClipAreaPoints = info.antiClipArea;
m_currentAntiClipSensitivity = info.antiClipSensitivity;
m_currentNetworkInfomation = device->networkInfomation(); m_currentNetworkInfomation = device->networkInfomation();
m_currentFirmware = device->infomation().firmwareVersion; m_currentFirmware = device->infomation().firmwareVersion;
m_currentDeviceConnected = device->isConnected(); m_currentDeviceConnected = device->isConnected();
m_currentDeviceFlip = info.flip; m_currentDeviceFlip = info.flip;
m_currentDeviceRotation = info.rotation; m_currentDeviceRotation = info.rotation;
m_currentHelmetThreshold = info.helmetThreshold;
m_currentHeadThreshold = info.headThreshold;
m_currentDetectFrameSize = info.detectFrameSize;
emit currentDeviceRotationChanged(); emit currentDeviceRotationChanged();
emit currentDeviceFlipChanged(); emit currentDeviceFlipChanged();
emit currentOpenDoorAreaPointsChanged(); emit currentOpenDoorAreaPointsChanged();
@ -343,10 +273,6 @@ void Application::connectToDevice(int index) {
emit currentOpenDoorAreaWayChanged(); emit currentOpenDoorAreaWayChanged();
emit currentShieldedAreaEnabledChanged(); emit currentShieldedAreaEnabledChanged();
emit currentAntiClipAreaEnabledChanged(); emit currentAntiClipAreaEnabledChanged();
emit currentAntiClipSensitivityChanged();
emit currentHelmetThresholdChanged();
emit currentHeadThresholdChanged();
emit currentDetectFrameSizeChanged();
emit currentNetworkInfomationChanged(); emit currentNetworkInfomationChanged();
} }
emit currentFirmwareChanged(); emit currentFirmwareChanged();
@ -380,16 +306,6 @@ void Application::upgradeDevice(const QString &file) {
} }
} }
void Application::resetDevice() {
if (m_device.expired()) return;
auto device = m_device.lock();
if (device->isConnected()) {
device->requestReset();
} else {
emit newMessage(2, "恢复出厂设置", "设备已离线,请重新连接设备!");
}
}
void Application::onDeviceOpenDoorArea(DeviceConnection::AreaWay way, const QList<QPointF> &points) { void Application::onDeviceOpenDoorArea(DeviceConnection::AreaWay way, const QList<QPointF> &points) {
setCurrentOpenDoorAreaWay(way); setCurrentOpenDoorAreaWay(way);
setCurrentOpenDoorAreaPoints(points); setCurrentOpenDoorAreaPoints(points);
@ -407,16 +323,9 @@ void Application::onDeviceShieldedArea(bool enabled, const QList<QPointF> &point
setCurrentShieldedAreaPoints(points); setCurrentShieldedAreaPoints(points);
} }
void Application::onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points, int sensitivity) { void Application::onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points) {
setCurrentAntiClipAreaEnabled(enabled); setCurrentAntiClipAreaEnabled(enabled);
setCurrentAntiClipAreaPoints(points); setCurrentAntiClipAreaPoints(points);
setCurrentAntiClipSensitivity(sensitivity);
}
void Application::onDeviceDetectThresholdChanged(int helmetThreshold, int headThreshold, int detectFrameSize) {
setCurrentHelmetThreshold(helmetThreshold);
setCurrentHeadThreshold(headThreshold);
setCurrentDetectFrameSize(detectFrameSize);
} }
void Application::onDeviceNetworkInfomation(const NetworkInfomation &info) { void Application::onDeviceNetworkInfomation(const NetworkInfomation &info) {

View File

@ -34,13 +34,6 @@ class Application : public QObject {
setCurrentShieldedAreaPoints NOTIFY currentShieldedAreaPointsChanged) setCurrentShieldedAreaPoints NOTIFY currentShieldedAreaPointsChanged)
Q_PROPERTY(bool currentAntiClipAreaEnabled READ currentAntiClipAreaEnabled WRITE setCurrentAntiClipAreaEnabled Q_PROPERTY(bool currentAntiClipAreaEnabled READ currentAntiClipAreaEnabled WRITE setCurrentAntiClipAreaEnabled
NOTIFY currentAntiClipAreaEnabledChanged) NOTIFY currentAntiClipAreaEnabledChanged)
Q_PROPERTY(int currentAntiClipSensitivity READ currentAntiClipSensitivity WRITE setCurrentAntiClipSensitivity NOTIFY currentAntiClipSensitivityChanged)
Q_PROPERTY(int currentHelmetThreshold READ currentHelmetThreshold WRITE setCurrentHelmetThreshold NOTIFY
currentHelmetThresholdChanged)
Q_PROPERTY(int currentHeadThreshold READ currentHeadThreshold WRITE setCurrentHeadThreshold NOTIFY
currentHeadThresholdChanged)
Q_PROPERTY(int currentDetectFrameSize READ currentDetectFrameSize WRITE setCurrentDetectFrameSize NOTIFY
currentDetectFrameSizeChanged)
Q_PROPERTY(QList<QPointF> currentAntiClipAreaPoints READ currentAntiClipAreaPoints WRITE Q_PROPERTY(QList<QPointF> currentAntiClipAreaPoints READ currentAntiClipAreaPoints WRITE
setCurrentAntiClipAreaPoints NOTIFY currentAntiClipAreaPointsChanged) setCurrentAntiClipAreaPoints NOTIFY currentAntiClipAreaPointsChanged)
Q_PROPERTY( Q_PROPERTY(
@ -72,8 +65,6 @@ public:
bool currentAntiClipAreaEnabled() const; bool currentAntiClipAreaEnabled() const;
void setCurrentAntiClipAreaEnabled(bool enabled); void setCurrentAntiClipAreaEnabled(bool enabled);
int currentAntiClipSensitivity() const;
void setCurrentAntiClipSensitivity(int sensitivity);
QList<QPointF> currentAntiClipAreaPoints() const; QList<QPointF> currentAntiClipAreaPoints() const;
void setCurrentAntiClipAreaPoints(const QList<QPointF> &points); void setCurrentAntiClipAreaPoints(const QList<QPointF> &points);
@ -83,15 +74,6 @@ public:
int currentDeviceRotation() const; int currentDeviceRotation() const;
void setCurrentDeviceRotation(int rotation); void setCurrentDeviceRotation(int rotation);
int currentHelmetThreshold() const;
void setCurrentHelmetThreshold(int threshold);
int currentHeadThreshold() const;
void setCurrentHeadThreshold(int threshold);
int currentDetectFrameSize() const;
void setCurrentDetectFrameSize(int size);
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);
@ -99,7 +81,6 @@ public:
const QString &gateway, const QString &dns); const QString &gateway, const QString &dns);
Q_INVOKABLE void connectToDevice(int index); Q_INVOKABLE void connectToDevice(int index);
Q_INVOKABLE void upgradeDevice(const QString &file); Q_INVOKABLE void upgradeDevice(const QString &file);
Q_INVOKABLE void resetDevice();
Q_INVOKABLE void startSearchDevice(); Q_INVOKABLE void startSearchDevice();
int exec(); int exec();
@ -113,10 +94,6 @@ signals:
void currentOpenDoorAreaWayChanged(); void currentOpenDoorAreaWayChanged();
void currentShieldedAreaEnabledChanged(); void currentShieldedAreaEnabledChanged();
void currentAntiClipAreaEnabledChanged(); void currentAntiClipAreaEnabledChanged();
void currentAntiClipSensitivityChanged();
void currentHelmetThresholdChanged();
void currentDetectFrameSizeChanged();
void currentHeadThresholdChanged();
void currentNetworkInfomationChanged(); void currentNetworkInfomationChanged();
void currentFirmwareChanged(); void currentFirmwareChanged();
void currentDeviceConnectedChanged(); void currentDeviceConnectedChanged();
@ -131,8 +108,7 @@ protected:
void onDeviceFlipChanged(bool flip); void onDeviceFlipChanged(bool flip);
void onDeviceOpenDoorArea(DeviceConnection::AreaWay way, 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, int sensitivity); void onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points);
void onDeviceDetectThresholdChanged(int helmetThreshold, int headThreshold, int detectFrameSize);
void onDeviceNetworkInfomation(const NetworkInfomation &info); void onDeviceNetworkInfomation(const NetworkInfomation &info);
void onDeviceFirmware(const QString &firmware); void onDeviceFirmware(const QString &firmware);
void onDeviceConnected(); void onDeviceConnected();
@ -152,16 +128,12 @@ private:
bool m_currentShieldedAreaEnabled = false; bool m_currentShieldedAreaEnabled = false;
QList<QPointF> m_currentShieldedAreaPoints; QList<QPointF> m_currentShieldedAreaPoints;
bool m_currentAntiClipAreaEnabled = false; bool m_currentAntiClipAreaEnabled = false;
int m_currentAntiClipSensitivity = 1;
QList<QPointF> m_currentAntiClipAreaPoints; QList<QPointF> m_currentAntiClipAreaPoints;
NetworkInfomation m_currentNetworkInfomation; NetworkInfomation m_currentNetworkInfomation;
QString m_currentFirmware; QString m_currentFirmware;
bool m_currentDeviceConnected = false; bool m_currentDeviceConnected = false;
bool m_currentDeviceFlip = false; bool m_currentDeviceFlip = false;
int m_currentDeviceRotation = 0; int m_currentDeviceRotation = 0;
int m_currentHelmetThreshold = 1;
int m_currentHeadThreshold = 2;
int m_currentDetectFrameSize = 3;
}; };
#endif // APPLICATION_H #endif // APPLICATION_H

View File

@ -1,17 +1,12 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(AntiClipSettings VERSION 1.8 LANGUAGES C CXX) project(AntiClipSettings VERSION 1.6 LANGUAGES C CXX)
set(APPLICATION_NAME "视觉防夹设备上位机工具") set(APPLICATION_NAME "视觉防夹设备上位机工具")
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(LINUX) set(Libraries_ROOT E:/Projects/Libraries CACHE STRING "Libraries directory.")
set(Libraries_ROOT /opt/Libraries CACHE STRING "Libraries directory.")
else()
set(Libraries_ROOT E:/Projects/Libraries CACHE STRING "Libraries directory.")
endif()
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Qml Quick Network QuickControls2) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Qml Quick Network QuickControls2)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Qml Quick Network QuickControls2) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Qml Quick Network QuickControls2)
@ -29,11 +24,7 @@ else()
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>") add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
if(LINUX) set(BOOST_ROOT ${Libraries_ROOT}/boost_1_83_0_msvc2022_64bit)
set(BOOST_ROOT ${Libraries_ROOT}/boost_1_83_0)
else()
set(BOOST_ROOT ${Libraries_ROOT}/boost_1_83_0_msvc2022_64bit)
endif()
set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include/boost-1_83) set(Boost_INCLUDE_DIR ${BOOST_ROOT}/include/boost-1_83)
set(FFmpeg_ROOT ${Libraries_ROOT}/ffmpeg-6.1.1-full_build-shared) set(FFmpeg_ROOT ${Libraries_ROOT}/ffmpeg-6.1.1-full_build-shared)
endif() endif()
@ -48,13 +39,8 @@ set(FFmpeg_INCLUDE_DIR ${FFmpeg_ROOT}/include)
set(FFmpeg_LIB_DIR ${FFmpeg_ROOT}/lib) set(FFmpeg_LIB_DIR ${FFmpeg_ROOT}/lib)
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
if(LINUX) set(JPEGTURBO_ROOT ${Libraries_ROOT}/libjpeg-turbo-3.0.3_msvc2022_64bit_debug)
set(MBEDTLS_ROOT ${Libraries_ROOT}/mbedtls-3.6.2) set(MBEDTLS_ROOT ${Libraries_ROOT}/mbedtls-3.6.2_msvc2022_64bit_debug)
set(JPEGTURBO_ROOT ${Libraries_ROOT}/libjpeg-turbo-3.1.0)
else()
set(MBEDTLS_ROOT ${Libraries_ROOT}/mbedtls-3.6.2_msvc2022_64bit_debug)
set(JPEGTURBO_ROOT ${Libraries_ROOT}/libjpeg-turbo-3.0.3_msvc2022_64bit_debug)
endif()
else() else()
set(JPEGTURBO_ROOT ${Libraries_ROOT}/libjpeg-turbo-3.0.3_msvc2022_64bit_release) set(JPEGTURBO_ROOT ${Libraries_ROOT}/libjpeg-turbo-3.0.3_msvc2022_64bit_release)
set(MBEDTLS_ROOT ${Libraries_ROOT}/mbedtls-3.6.2_msvc2022_64bit_release) set(MBEDTLS_ROOT ${Libraries_ROOT}/mbedtls-3.6.2_msvc2022_64bit_release)
@ -151,9 +137,8 @@ target_link_libraries(AntiClipSettings
PRIVATE avformat PRIVATE avformat
PRIVATE Universal PRIVATE Universal
PRIVATE Encrypt PRIVATE Encrypt
$<$<PLATFORM_ID:Linux>:turbojpeg> PRIVATE turbojpeg-static
$<$<PLATFORM_ID:Windows>:turbojpeg-static> PRIVATE Ws2_32
$<$<PLATFORM_ID:Windows>:Ws2_32>
) )
include(GNUInstallDirs) include(GNUInstallDirs)

View File

@ -5,17 +5,13 @@
#include <QPointF> #include <QPointF>
#include <QTimer> #include <QTimer>
#include <QTimerEvent> #include <QTimerEvent>
#include <WinSock2.h>
#include <boost/json/object.hpp> #include <boost/json/object.hpp>
#include <boost/json/parse.hpp> #include <boost/json/parse.hpp>
#include <boost/json/serialize.hpp> #include <boost/json/serialize.hpp>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <mbedtls/md5.h> #include <mbedtls/md5.h>
#ifdef Q_OS_LINUX
#include <arpa/inet.h>
#else
#include <WinSock2.h>
#endif
DeviceConnection::DeviceConnection(QObject *parent) : QObject{parent} { DeviceConnection::DeviceConnection(QObject *parent) : QObject{parent} {
} }
@ -214,16 +210,15 @@ void DeviceConnection::requestAntiClipArea() {
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::updateAntiClipAreaPoints(bool enabled, const QList<QPointF> &points, int sensitivity) { void DeviceConnection::updateAntiClipAreaPoints(bool enabled, const QList<QPointF> &points) {
Task task; Task task;
task.command = "a03opendoor5_setdata"; task.command = "a03opendoor5_setdata";
task.task = [this, enabled, points, sensitivity]() { task.task = [this, enabled, points]() {
boost::json::object request; boost::json::object request;
request["func"] = "a03opendoor5_setdata"; request["func"] = "a03opendoor5_setdata";
request["deviceid"] = "0"; request["deviceid"] = "0";
boost::json::object data; boost::json::object data;
data["value"] = enabled ? "1" : "0"; data["value"] = enabled ? "1" : "0";
data["sensitivity"] = std::to_string(sensitivity);
boost::json::array pointArray; boost::json::array pointArray;
for (auto &p : points) { for (auto &p : points) {
boost::json::object point; boost::json::object point;
@ -244,56 +239,6 @@ void DeviceConnection::updateAntiClipAreaPoints(bool enabled, const QList<QPoint
m_requests.push(task); m_requests.push(task);
} }
QFuture<bool> DeviceConnection::updateDetectThreshold(int helmetThreshold, int headThreshold, int detectFrameSize) {
constexpr auto command = "headdetectparam_setdata";
Task task;
task.command = command;
task.task = [this, helmetThreshold, headThreshold, detectFrameSize, command]() {
boost::json::object request;
request["func"] = command;
request["deviceid"] = "0";
boost::json::object data;
if (headThreshold >= 0) {
data["headthreshold"] = headThreshold;
}
if (helmetThreshold >= 0) {
data["hatthreshold"] = helmetThreshold;
}
if (detectFrameSize >= 0) {
data["detectframenum"] = detectFrameSize;
}
request["data"] = std::move(data);
auto text = boost::json::serialize(request);
m_commandSocket->write(text.data(), text.size());
};
task.future = std::make_shared<QFutureInterface<bool>>();
if (m_requests.empty()) {
task.task();
}
auto ret = task.future->future();
m_requests.push(task);
return ret;
}
void DeviceConnection::requestHeadDetectThreshold() {
constexpr auto command = "headdetectparam_getdata";
Task task;
task.command = command;
task.task = [this, command]() {
boost::json::object request;
request["func"] = command;
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());
};
if (m_requests.empty()) {
task.task();
}
m_requests.push(task);
}
void DeviceConnection::requestResolution(Resolution resolution) { void DeviceConnection::requestResolution(Resolution resolution) {
Task task; Task task;
task.command = "quality_setdata"; task.command = "quality_setdata";
@ -453,11 +398,7 @@ void DeviceConnection::requestOta(const QString &firmware, const QString &file)
Task task; Task task;
task.command = "a22devicefirmware_setdata"; task.command = "a22devicefirmware_setdata";
task.task = [this, file, firmware]() { task.task = [this, file, firmware]() {
#ifdef Q_OS_LINUX
std::ifstream ifs(file.toStdString(), std::ifstream::binary);
#else
std::ifstream ifs(Amass::StringUtility::UTF8ToGBK(file.toStdString()), std::ifstream::binary); std::ifstream ifs(Amass::StringUtility::UTF8ToGBK(file.toStdString()), std::ifstream::binary);
#endif
m_uploadBuffer = std::vector<uint8_t>((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); m_uploadBuffer = std::vector<uint8_t>((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
m_sendedSize = 0; m_sendedSize = 0;
@ -492,36 +433,10 @@ void DeviceConnection::requestOta(const QString &firmware, const QString &file)
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::requestReset() {
Task task;
task.command = "a12factory_setdata";
task.task = [this]() {
boost::json::object request;
request["func"] = "a12factory_setdata";
request["deviceid"] = "0";
boost::json::object data;
data["value"] = "1";
request["data"] = std::move(data);
auto text = boost::json::serialize(request);
m_commandSocket->write(text.data(), text.size());
};
task.future = std::make_shared<QFutureInterface<bool>>();
if (m_requests.empty()) {
task.task();
}
auto ret = task.future->future();
m_requests.push(task);
}
void DeviceConnection::transferBinContent() { void DeviceConnection::transferBinContent() {
constexpr int SliceSize = 1024; constexpr int SliceSize = 1024;
constexpr int WaitMd5CheckTime = 3000; // ms constexpr int WaitMd5CheckTime = 3000; // ms
if (m_sendedSize >= m_uploadBuffer.size()) { if (m_sendedSize >= m_uploadBuffer.size()) return;
LOG(warning) << "file size is wrong, sended size: " << m_sendedSize
<< "ota file size: " << m_uploadBuffer.size();
return;
}
char buffer[1 + sizeof(int32_t) + 1024]; char buffer[1 + sizeof(int32_t) + 1024];
int sendSize = SliceSize; int sendSize = SliceSize;
@ -630,10 +545,7 @@ QString DeviceConnection::handleCommand(const std::string_view &replyText, const
} }
m_infomation.antiClipAreaEnabled = value == "1"; m_infomation.antiClipAreaEnabled = value == "1";
m_infomation.antiClipArea = points; m_infomation.antiClipArea = points;
if (data.contains("sensitivity")) { emit antiClipAreaChanged(value == "1", points);
m_infomation.antiClipSensitivity = std::stoi(static_cast<std::string>(data.at("sensitivity").as_string()));
}
emit antiClipAreaChanged(value == "1", points, m_infomation.antiClipSensitivity);
} else if (function == "netconfig_getdata") { } else if (function == "netconfig_getdata") {
auto &data = reply.at("data").as_object(); auto &data = reply.at("data").as_object();
m_networkInfomation.dhcp = data.at("type").as_string() == "dhcp"; m_networkInfomation.dhcp = data.at("type").as_string() == "dhcp";
@ -757,31 +669,6 @@ QString DeviceConnection::handleCommand(const std::string_view &replyText, const
} }
} }
requestVideoInformation(); requestVideoInformation();
} else if (function == "a12factory_setdata") {
LOG(info) << "device factory reset";
} else if (function == "headdetectparam_getdata") {
auto &data = reply.at("data").as_object();
if (data.contains("hatthreshold")) {
m_infomation.helmetThreshold = data.at("hatthreshold").as_int64();
}
if (data.contains("headthreshold")) {
m_infomation.headThreshold = data.at("headthreshold").as_int64();
}
if (data.contains("detectframenum")) {
m_infomation.detectFrameSize = data.at("detectframenum").as_int64();
}
emit detectThresholdChanged(m_infomation.helmetThreshold, m_infomation.headThreshold,
m_infomation.detectFrameSize);
} else if (function == "thresholdwithhat_setdata") {
if ((task != nullptr) && (task->command.toStdString() == function)) {
if (task->timeoutTimer) {
task->timeoutTimer->stop();
}
bool status = true;
if (task->future) {
task->future->reportFinished(&status);
}
}
} else { } else {
LOG(warning) << "unknown reply: " << replyText; LOG(warning) << "unknown reply: " << replyText;
} }
@ -797,7 +684,6 @@ void DeviceConnection::onConnected() {
requestAntiClipArea(); requestAntiClipArea();
requestNetworkInfomation(); requestNetworkInfomation();
requestVideoInformation(); requestVideoInformation();
requestHeadDetectThreshold();
emit connected(); emit connected();
m_heartbeatTimerId = startTimer(2500); m_heartbeatTimerId = startTimer(2500);
if (m_otaProgress == 99) { if (m_otaProgress == 99) {

View File

@ -9,10 +9,8 @@
#include <QTcpSocket> #include <QTcpSocket>
#include <queue> #include <queue>
#include <string_view> #include <string_view>
#include <QPointF>
class NetworkInfomation; class NetworkInfomation;
class QTimer;
class DeviceConnection : public QObject { class DeviceConnection : public QObject {
Q_OBJECT Q_OBJECT
@ -49,10 +47,6 @@ public:
QList<QPointF> antiClipArea; QList<QPointF> antiClipArea;
bool antiClipAreaEnabled; bool antiClipAreaEnabled;
int antiClipSensitivity = 1;
int helmetThreshold = 1;
int headThreshold = 1;
int detectFrameSize = 1;
}; };
Q_ENUM(AreaWay) Q_ENUM(AreaWay)
@ -73,11 +67,9 @@ public:
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, int sensitivity); void updateAntiClipAreaPoints(bool enabled, const QList<QPointF> &points);
void requestResolution(Resolution resolution); void requestResolution(Resolution resolution);
void requestNetworkInfomation(); void requestNetworkInfomation();
QFuture<bool> updateDetectThreshold(int helmetThreshold, int headThreshold, int detectFrameSize);
void requestHeadDetectThreshold();
QFuture<bool> updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway, QFuture<bool> updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway,
const QString &dns); const QString &dns);
void requestVersion(); void requestVersion();
@ -95,17 +87,15 @@ public:
* @param file * @param file
*/ */
void requestOta(const QString &firmware, const QString &file); void requestOta(const QString &firmware, const QString &file);
void requestReset();
signals: signals:
void connected(); void connected();
void disconnected(); void disconnected();
void openDoorAreaChanged(AreaWay way, const QList<QPointF> &points); void openDoorAreaChanged(AreaWay way, const QList<QPointF> &points);
void shieldedAreaChanged(bool enabled, const QList<QPointF> &points); void shieldedAreaChanged(bool enabled, const QList<QPointF> &points);
void antiClipAreaChanged(bool enabled, const QList<QPointF> &points, int sensitivity); void antiClipAreaChanged(bool enabled, const QList<QPointF> &points);
void rotationChanged(int rotation); void rotationChanged(int rotation);
void flipChanged(bool flip); void flipChanged(bool flip);
void detectThresholdChanged(int helmetThreshold, int headThreshold, int detectFrameSize);
void networkInfomationChanged(const NetworkInfomation &info); void networkInfomationChanged(const NetworkInfomation &info);
void firmwareChanged(const QString &firmware); void firmwareChanged(const QString &firmware);
void otaProgressChanged(bool status, int progress, const QString &message); void otaProgressChanged(bool status, int progress, const QString &message);

View File

@ -139,8 +139,6 @@ void DeviceListModel::startSearchDevice() {
emit searchProgressChanged(); emit searchProgressChanged();
m_timerId = startTimer(1000); m_timerId = startTimer(1000);
emit isSearchingChanged(); emit isSearchingChanged();
} else {
LOG(warning) << "cannot creat udp sockets.";
} }
} }

View File

@ -16,10 +16,6 @@ Item {
property color antiClipAreaColor: "blue" property color antiClipAreaColor: "blue"
property var antiClipAreaPoints: [] property var antiClipAreaPoints: []
property bool antiClipAreaEnabled: false property bool antiClipAreaEnabled: false
property int antiClipSensitivity: 1
property alias helmetThreshold: helmetInput.text
property alias headThreshold: headInput.text
property alias detectFrameSize: detectFrameInput.text
property alias flip: flipSwitch.checked property alias flip: flipSwitch.checked
property alias videoRotation: rotateComboBox.currentIndex property alias videoRotation: rotateComboBox.currentIndex
@ -245,12 +241,14 @@ Item {
} }
} }
} }
GridLayout { 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
columns: 2 columns: 2
spacing: 10
verticalItemAlignment: Qt.AlignVCenter
Label { text: qsTr("图像: ") } Label { text: qsTr("图像: ") }
@ -283,7 +281,6 @@ Item {
Label { Label {
text: qsTr("开门区域: ") text: qsTr("开门区域: ")
} }
Row { Row {
enabled: root.enabled enabled: root.enabled
RadioButton { RadioButton {
@ -309,141 +306,28 @@ Item {
} }
} }
Label {
Layout.alignment: Qt.AlignTop Label {text: qsTr("防夹区域: ")}
Layout.topMargin: 14 Row {
text: qsTr("防夹区域: ") enabled: root.enabled
RadioButton {
text: "关闭"
checked: !App.currentAntiClipAreaEnabled
onToggled: {
App.currentAntiClipAreaEnabled=false
}
}
RadioButton {
text: "四边形"
checked: App.currentAntiClipAreaEnabled
onToggled: {
App.currentAntiClipAreaEnabled=true
}
}
} }
Flow{
Layout.fillHeight: true
Layout.fillWidth: true
RowLayout {
enabled: root.enabled
RadioButton {
text: "关闭"
checked: !App.currentAntiClipAreaEnabled
onToggled: {
App.currentAntiClipAreaEnabled=false
}
}
RadioButton {
text: "四边形"
checked: App.currentAntiClipAreaEnabled
onToggled: {
App.currentAntiClipAreaEnabled=true
}
Layout.rightMargin: 20
}
}
RowLayout {
Label { text: qsTr("灵敏度: ")
Layout.alignment: Qt.AlignRight
}
ComboBox {
id: antiClipSensitivityComboBox
enabled: root.enabled
implicitWidth: 60
Layout.alignment: Qt.AlignLeft
model: [1,2,3,4,5]
currentIndex: root.antiClipSensitivity-1
onCurrentIndexChanged: {
App.currentAntiClipSensitivity = antiClipSensitivityComboBox.currentIndex+1
}
Layout.rightMargin: 20
}
}
}
Label {
Layout.alignment: Qt.AlignTop
Layout.topMargin: 14
text: qsTr("阈值设置: ")
}
Flow {
Layout.fillHeight: true
Layout.fillWidth: true
RowLayout {
Label { text: qsTr("安全帽阈值: ")
Layout.alignment: Qt.AlignRight
}
TextField {
id: helmetInput
enabled: root.enabled
implicitWidth: 60
Layout.alignment: Qt.AlignLeft
selectByMouse: true
ToolTip.visible: helmetInput.hovered
ToolTip.text: "阈值范围 0-300"
validator: IntValidator {
bottom: 0
top: 300
}
Layout.rightMargin: 20
}
}
RowLayout {
Label { text: qsTr("头肩阈值: ")
Layout.alignment: Qt.AlignRight
}
TextField {
id: headInput
enabled: root.enabled
implicitWidth: 60
Layout.alignment: Qt.AlignLeft
selectByMouse: true
ToolTip.visible: headInput.hovered
ToolTip.text: "阈值范围 0-300"
validator: IntValidator {
bottom: 0
top: 300
}
Layout.rightMargin: 20
}
}
RowLayout {
Label { text: qsTr("识别帧数: ")
Layout.alignment: Qt.AlignRight
}
TextField {
id: detectFrameInput
enabled: root.enabled
implicitWidth: 60
Layout.alignment: Qt.AlignLeft
selectByMouse: true
ToolTip.visible: detectFrameInput.hovered
ToolTip.text: "帧数范围 0-30"
validator: IntValidator {
bottom: 0
top: 30
}
}
}
Button {
enabled: root.enabled
text: "保存"
onClicked: {
if(App.currentHelmetThreshold !== parseInt(helmetInput.text)){
App.currentHelmetThreshold= parseInt(helmetInput.text)
window.showSuccess("安全帽阈值设置成功",2500)
}
if(App.currentHeadThreshold !== parseInt(headInput.text)){
App.currentHeadThreshold= parseInt(headInput.text)
window.showSuccess("头肩阈值设置成功",2500)
}
if(App.currentDetectFrameSize !== parseInt(detectFrameInput.text)){
App.currentDetectFrameSize= parseInt(detectFrameInput.text)
window.showSuccess("识别帧数设置成功",2500)
}
}
}
}
Label {text: qsTr("屏蔽区域: ")} Label {text: qsTr("屏蔽区域: ")}
Row { Row {
id: shieldedRow id: shieldedRow

View File

@ -48,8 +48,7 @@ ApplicationWindow {
id: emptyHint id: emptyHint
visible: false visible: false
anchors.centerIn: parent anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter text: qsTr("未搜索到设备")
text: qsTr("未搜索到设备\n请尝试关闭Windows防火墙后再重试")
} }
delegate: Rectangle { delegate: Rectangle {
width: deviceList.width width: deviceList.width
@ -119,11 +118,7 @@ ApplicationWindow {
shieldedAreaEnabled: App.currentShieldedAreaEnabled shieldedAreaEnabled: App.currentShieldedAreaEnabled
shieldedAreaPoints: App.currentShieldedAreaPoints shieldedAreaPoints: App.currentShieldedAreaPoints
antiClipAreaEnabled: App.currentAntiClipAreaEnabled antiClipAreaEnabled: App.currentAntiClipAreaEnabled
antiClipSensitivity: App.currentAntiClipSensitivity
antiClipAreaPoints: App.currentAntiClipAreaPoints antiClipAreaPoints: App.currentAntiClipAreaPoints
helmetThreshold: App.currentHelmetThreshold
headThreshold: App.currentHeadThreshold
detectFrameSize: App.currentDetectFrameSize
flip: App.currentDeviceFlip flip: App.currentDeviceFlip
videoRotation: App.currentDeviceRotation videoRotation: App.currentDeviceRotation
} }
@ -156,9 +151,9 @@ ApplicationWindow {
} }
if (App.collector.path.length <= 0) { if (App.collector.path.length <= 0) {
showFolderDialog(folder => { showFolderDialog(folder => {
App.collector.path = folder App.collector.path = folder
App.collector.start(App.devices.get(deviceList.currentIndex).ip) App.collector.start(App.devices.get(deviceList.currentIndex).ip)
}) })
} else { } else {
App.collector.start(App.devices.get( App.collector.start(App.devices.get(
deviceList.currentIndex).ip) deviceList.currentIndex).ip)
@ -168,7 +163,6 @@ ApplicationWindow {
} }
Item {} Item {}
Button { Button {
Layout.alignment: Qt.AlignRight
text: "升级" text: "升级"
onClicked: { onClicked: {
if (deviceList.currentIndex < 0) { if (deviceList.currentIndex < 0) {
@ -181,41 +175,18 @@ ApplicationWindow {
otaPopup.open() otaPopup.open()
} }
} }
Button { Item {}
Layout.alignment: Qt.AlignRight
Layout.rightMargin: 5
text: "重置"
onClicked: {
if (deviceList.currentIndex < 0) {
showMessageDialog(2, "恢复出厂设置", "请先选择设备")
return
} else {
showMessageDialog(2, "恢复出厂设置", "设备将会重启,重启后配置恢复默认", () => {
App.resetDevice()
})
}
}
}
spacing: (parent.width - (2 * 100)) / 3 spacing: (parent.width - (2 * 100)) / 3
} }
MessageBar { function showMessageDialog(type, title, message) {
id: messageBar
root: window.contentItem
}
function showSuccess(text, duration) {
return messageBar.showSuccess(text, duration)
}
function showMessageDialog(type, title, message, callback) {
let component = Qt.createComponent("MessageDialog.qml") let component = Qt.createComponent("MessageDialog.qml")
if (component.status === Component.Ready) { if (component.status === Component.Ready) {
let dialog = component.createObject(window, { let dialog = component.createObject(window, {
"type": type, "type": type,
"titleText": title, "titleText": title,
"text": message, "text": message
"callback": callback })
})
dialog.open() dialog.open()
} }
} }
@ -228,14 +199,11 @@ ApplicationWindow {
dialog = Qt.createQmlObject("import QtQuick.Dialogs; FileDialog {}", window, "myDynamicSnippet") dialog = Qt.createQmlObject("import QtQuick.Dialogs; FileDialog {}", window, "myDynamicSnippet")
} }
if (dialog) { if (dialog) {
dialog.nameFilters = nameFilters dialog.nameFilters = nameFilters;
dialog.visible = true dialog.visible = true
dialog.accepted.connect(function () { dialog.accepted.connect(function () {
let fileUrl = isQt5 ? dialog.fileUrl.toString() : dialog.selectedFile.toString() let fileUrl = isQt5 ? dialog.fileUrl.toString() : dialog.selectedFile.toString()
let localFilePath = fileUrl let localFilePath = fileUrl.startsWith("file:///") ? fileUrl.substring(8) : fileUrl
if (fileUrl.startsWith("file:///")) {
localFilePath = fileUrl.substring(Qt.platform.os === "windows" ? 8 : 7)
}
onSelected(localFilePath) onSelected(localFilePath)
dialog.destroy() dialog.destroy()
}) })

View File

@ -1,101 +0,0 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
Object {
id: control
property var root
property var screenLayout: null
property int layoutY: 75
function showSuccess(text,duration=1000){
return create("success",text,duration)
}
function create(type,text,duration){
if(screenLayout){
let last = screenLayout.getLastloader()
if(last.type === type && last.text === text){
last.duration = duration
if (duration > 0) last.restart()
return last
}
} else {
initScreenLayout()
}
return contentComponent.createObject(screenLayout,{type:type,text:text,duration:duration,})
}
function initScreenLayout() {
if(control.screenLayout == null) {
control.screenLayout = screenLayoutComponent.createObject(root)
screenLayout.y = control.layoutY
screenLayout.z = 100000
}
}
Component {
id:contentComponent
Rectangle {
id: content
property int duration: 1500
property string type
property alias text: message.text
color: "#EBF8ED"
radius: 3.2
border.width: 1
border.color: Qt.darker(content.color)
layer.enabled: true
x:(parent.width - width) / 2
width: 200
height: 32
Row {
anchors.fill: parent
Image {
width: 32
height: 32
fillMode: Image.Pad
source: "qrc:/qt/qml/AntiClipSettings/resources/successfull.svg"
anchors.verticalCenter: parent.verticalCenter
}
Label {
id: message
anchors.verticalCenter: parent.verticalCenter
}
}
Timer {
id:delayTimer
interval: duration
running: duration > 0
repeat: duration > 0
onTriggered: content.close()
}
function close(){
content.destroy()
}
}
}
Component {
id:screenLayoutComponent
Column{
parent: Overlay.overlay
z:999
spacing: 5
width: root.width
move: Transition {
NumberAnimation {
properties: "y"
easing.type: Easing.InOutQuad
duration: 167
}
}
onChildrenChanged: if(children.length === 0) destroy()
function getLastloader(){
if(children.length > 0){
return children[children.length - 1]
}
return null
}
}
}
}

View File

@ -13,7 +13,6 @@ Dialog {
property alias text: textLabel.text property alias text: textLabel.text
property alias textFontSize: textLabel.font.pixelSize property alias textFontSize: textLabel.font.pixelSize
property int type: MessageDialog.Type.Successful property int type: MessageDialog.Type.Successful
property var callback
closePolicy: Popup.CloseOnEscap | Popup.NoAutoClose closePolicy: Popup.CloseOnEscap | Popup.NoAutoClose
background: Rectangle { background: Rectangle {
radius: 8 radius: 8
@ -63,60 +62,30 @@ Dialog {
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
} }
Row { Button {
id: cancelButton
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
Layout.rightMargin: 6 Layout.rightMargin: 6
spacing: 10 Layout.preferredWidth: 72
Button { Layout.preferredHeight: 40
id: okButton font.family: control.font.family
width: 72 text: "关闭"
height: 40 font.pixelSize: 14
font.family: control.font.family contentItem: Text {
text: "好的" text: parent.text
font.pixelSize: 14 font: parent.font
contentItem: Text { color: parent.down ? "#FFFFFF" : "#53627C"
text: parent.text horizontalAlignment: Text.AlignHCenter
font: parent.font verticalAlignment: Text.AlignVCenter
color: parent.down ? "#FFFFFF" : "#53627C"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
background: Rectangle {
border.color: "#E1E4E8"
border.width: 1
color: parent.down ? "#F25959" : "#FFFFFF"
radius: 2
}
onClicked: {
if(callback !== undefined){
callback()
}
control.accept()
}
} }
Button {
id: cancelButton background: Rectangle {
visible: callback !== undefined border.color: "#E1E4E8"
width: 72 border.width: 1
height: 40 color: parent.down ? "#F25959" : "#FFFFFF"
font.family: control.font.family radius: 2
text: "取消"
font.pixelSize: 14
contentItem: Text {
text: parent.text
font: parent.font
color: parent.down ? "#FFFFFF" : "#53627C"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
background: Rectangle {
border.color: "#E1E4E8"
border.width: 1
color: parent.down ? "#F25959" : "#FFFFFF"
radius: 2
}
onClicked: control.reject()
} }
onClicked: control.reject()
} }
} }
onTypeChanged: { onTypeChanged: {

View File

@ -1,5 +0,0 @@
import QtQml 2.15
QtObject {
default property list<QtObject> children
}

View File

@ -41,7 +41,6 @@ Popup {
Layout.fillWidth: true Layout.fillWidth: true
readOnly: true readOnly: true
placeholderText: "请选择升级bin文件" placeholderText: "请选择升级bin文件"
selectByMouse: true
} }
Button { Button {
enabled: otaFinished enabled: otaFinished