diff --git a/Application.cpp b/Application.cpp index 63201ac..f1c82c7 100644 --- a/Application.cpp +++ b/Application.cpp @@ -155,10 +155,14 @@ void Application::connectToDevice(int index) { disconnect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea); disconnect(device.get(), &DeviceConnection::networkInfomationChanged, this, &Application::onDeviceNetworkInfomation); + disconnect(device.get(), &DeviceConnection::firmwareChanged, this, &Application::onDeviceFirmware); disconnect(device.get(), &DeviceConnection::otaProgressChanged, this, &Application::currentDeviceOtaProgressChanged); device->setH264FrameCallback(DeviceConnection::H264FrameCallback()); device->setLiveStreamEnabled(false); + if (!m_currentFirmware.isEmpty()) { + m_currentFirmware.clear(); + } } if (index >= 0) { auto device = m_devices->device(index); @@ -169,6 +173,7 @@ void Application::connectToDevice(int index) { connect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea); connect(device.get(), &DeviceConnection::networkInfomationChanged, this, &Application::onDeviceNetworkInfomation); + connect(device.get(), &DeviceConnection::firmwareChanged, this, &Application::onDeviceFirmware); connect(device.get(), &DeviceConnection::otaProgressChanged, this, &Application::currentDeviceOtaProgressChanged); device->setH264FrameCallback([this](const char *data, uint32_t size) { @@ -180,7 +185,6 @@ void Application::connectToDevice(int index) { }); device->setLiveStreamEnabled(true); auto area = device->area(); - m_currentOpenDoorAreaWay = area.openDoorAreaWay; m_currentOpenDoorAreaPoints = area.openDoorArea; m_currentShieldedAreaEnabled = area.shieldedAreaEnabled; @@ -188,6 +192,7 @@ void Application::connectToDevice(int index) { m_currentAntiClipAreaEnabled = area.antiClipAreaEnabled; m_currentAntiClipAreaPoints = area.antiClipArea; m_currentNetworkInfomation = device->networkInfomation(); + m_currentFirmware = device->infomation().firmwareVersion; emit currentOpenDoorAreaPointsChanged(); emit currentShieldedAreaPointsChanged(); emit currentAntiClipAreaPointsChanged(); @@ -196,6 +201,7 @@ void Application::connectToDevice(int index) { emit currentAntiClipAreaEnabledChanged(); emit currentNetworkInfomationChanged(); } + emit currentFirmwareChanged(); } void Application::startSearchDevice() { @@ -216,7 +222,6 @@ void Application::onDeviceOpenDoorArea(DeviceConnection::AreaWay way, const QLis } void Application::onDeviceShieldedArea(bool enabled, const QList &points) { - LOG(info) << "onDeviceShieldedArea: " << points.size(); setCurrentShieldedAreaEnabled(enabled); setCurrentShieldedAreaPoints(points); } @@ -231,6 +236,13 @@ void Application::onDeviceNetworkInfomation(const NetworkInfomation &info) { emit currentNetworkInfomationChanged(); } +void Application::onDeviceFirmware(const QString &firmware) { + if (m_currentFirmware != firmware) { + m_currentFirmware = firmware; + emit currentFirmwareChanged(); + } +} + int Application::exec() { QQmlApplicationEngine engine; engine.addImageProvider("videoframe", m_videoFrameProvider); diff --git a/Application.h b/Application.h index fbb7e0d..f40e4d5 100644 --- a/Application.h +++ b/Application.h @@ -37,6 +37,7 @@ class Application : public QObject { setCurrentAntiClipAreaPoints NOTIFY currentAntiClipAreaPointsChanged) Q_PROPERTY( NetworkInfomation currentNetworkInfomation READ currentNetworkInfomation NOTIFY currentNetworkInfomationChanged) + Q_PROPERTY(QString currentFirmware MEMBER m_currentFirmware NOTIFY currentFirmwareChanged) friend class Amass::Singleton; public: @@ -82,6 +83,7 @@ signals: void currentShieldedAreaEnabledChanged(); void currentAntiClipAreaEnabledChanged(); void currentNetworkInfomationChanged(); + void currentFirmwareChanged(); void currentDeviceOtaProgressChanged(bool status, int progress, const QString &message); protected: @@ -90,6 +92,7 @@ protected: void onDeviceShieldedArea(bool enabled, const QList &points); void onDeviceAntiClipArea(bool enabled, const QList &points); void onDeviceNetworkInfomation(const NetworkInfomation &info); + void onDeviceFirmware(const QString &firmware); private: std::shared_ptr m_app; @@ -106,6 +109,7 @@ private: bool m_currentAntiClipAreaEnabled = false; QList m_currentAntiClipAreaPoints; NetworkInfomation m_currentNetworkInfomation; + QString m_currentFirmware; }; #endif // APPLICATION_H diff --git a/CMakeLists.txt b/CMakeLists.txt index 74ce391..597c099 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ qt_add_qml_module(AntiClipSettings qml/OtaPopup.qml qml/StatusTip.qml qml/DataCollectionPopup.qml + qml/IpTextField.qml RESOURCES resources/popup_close.svg resources/prompt_delete.svg diff --git a/DataStructure.h b/DataStructure.h index 2547e3f..efdc55c 100644 --- a/DataStructure.h +++ b/DataStructure.h @@ -13,7 +13,7 @@ struct NetworkInfomation { Q_PROPERTY(QString gateway MEMBER gateway) public: bool dhcp; - QString ip = "127.0..1"; + QString ip; QString netmask; QString gateway; }; diff --git a/DeviceConnection.cpp b/DeviceConnection.cpp index 55461f1..51ef701 100644 --- a/DeviceConnection.cpp +++ b/DeviceConnection.cpp @@ -30,7 +30,7 @@ bool DeviceConnection::isConnected() const { void DeviceConnection::connect(const Infomation &infomation) { m_infomation = infomation; m_commandSocket = new QTcpSocket(this); - QObject::connect(m_commandSocket, &QTcpSocket::disconnected, this, &DeviceConnection::disconnected); + QObject::connect(m_commandSocket, &QTcpSocket::disconnected, this, &DeviceConnection::onDisconnected); QObject::connect(m_commandSocket, &QTcpSocket::errorOccurred, this, &DeviceConnection::onErrorOccurred); m_h264Socket = new QTcpSocket(this); @@ -66,7 +66,9 @@ void DeviceConnection::setLiveStreamEnabled(bool enabled) { } void DeviceConnection::requestOpenDoorArea() { - auto task = [this]() { + Task task; + task.command = "a03opendoor1_getdata"; + task.task = [this]() { boost::json::object request; request["func"] = "a03opendoor1_getdata"; request["deviceid"] = "0"; @@ -74,16 +76,17 @@ void DeviceConnection::requestOpenDoorArea() { request["data"] = std::move(data); auto text = boost::json::serialize(request); m_commandSocket->write(text.data(), text.size()); - LOG(info) << "requestOpenDoorArea"; }; if (m_requests.empty()) { - task(); + task.task(); } m_requests.push(task); } void DeviceConnection::updateOpenDoorAreaPoints(AreaWay way, const QList &points) { - auto task = [this, way, points]() { + Task task; + task.command = "a03opendoor1_setdata"; + task.task = [this, way, points]() { boost::json::object request; request["func"] = "a03opendoor1_setdata"; request["deviceid"] = "0"; @@ -110,13 +113,15 @@ void DeviceConnection::updateOpenDoorAreaPoints(AreaWay way, const QListwrite(text.data(), text.size()); - LOG(info) << "requestShieldedArea"; }; if (m_requests.empty()) { - task(); + task.task(); } m_requests.push(task); } void DeviceConnection::updateShieldedAreaPoints(bool enabled, const QList &points) { - auto task = [this, enabled, points]() { + Task task; + task.command = "a03opendoor4_setdata"; + task.task = [this, enabled, points]() { boost::json::object request; request["func"] = "a03opendoor4_setdata"; request["deviceid"] = "0"; @@ -151,16 +157,17 @@ void DeviceConnection::updateShieldedAreaPoints(bool enabled, const QListwrite(text.data(), text.size()); - LOG(info) << "updateShieldedAreaPoints"; }; if (m_requests.empty()) { - task(); + task.task(); } m_requests.push(task); } void DeviceConnection::requestAntiClipArea() { - auto task = [this]() { + Task task; + task.command = "a03opendoor5_getdata"; + task.task = [this]() { boost::json::object request; request["func"] = "a03opendoor5_getdata"; request["deviceid"] = "0"; @@ -168,16 +175,17 @@ void DeviceConnection::requestAntiClipArea() { request["data"] = std::move(data); auto text = boost::json::serialize(request); m_commandSocket->write(text.data(), text.size()); - LOG(info) << "requestAntiClipArea"; }; if (m_requests.empty()) { - task(); + task.task(); } m_requests.push(task); } void DeviceConnection::updateAntiClipAreaPoints(bool enabled, const QList &points) { - auto task = [this, enabled, points]() { + Task task; + task.command = "a03opendoor5_setdata"; + task.task = [this, enabled, points]() { boost::json::object request; request["func"] = "a03opendoor5_setdata"; request["deviceid"] = "0"; @@ -198,13 +206,15 @@ void DeviceConnection::updateAntiClipAreaPoints(bool enabled, const QListwrite(text.data(), text.size()); - LOG(info) << "requestShieldedArea"; + LOG(info) << "requestResolution"; }; if (m_requests.empty()) { - task(); + task.task(); + } + m_requests.push(task); +} + +void DeviceConnection::requestVersion() { + Task task; + task.command = "a15devicedetail_getdata"; + task.task = [this]() { + boost::json::object request; + request["func"] = "a15devicedetail_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) << "requestVersion"; + }; + if (m_requests.empty()) { + task.task(); } m_requests.push(task); } void DeviceConnection::requestNetworkInfomation() { - auto task = [this]() { + Task task; + task.command = "netconfig_getdata"; + task.task = [this]() { boost::json::object request; request["func"] = "netconfig_getdata"; request["deviceid"] = "0"; @@ -233,14 +264,16 @@ void DeviceConnection::requestNetworkInfomation() { LOG(info) << "requestNetworkInfomation"; }; if (m_requests.empty()) { - task(); + task.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]() { + Task task; + task.command = "netconfig_setdata"; + task.task = [this, dhcp, ip, netmask, gateway]() { boost::json::object request; request["func"] = "netconfig_setdata"; request["deviceid"] = "0"; @@ -256,7 +289,7 @@ void DeviceConnection::updateNetworkInfomation(bool dhcp, const QString &ip, con LOG(info) << "requestUpdateNetworkInfomation"; }; if (m_requests.empty()) { - task(); + task.task(); } m_requests.push(task); } @@ -264,8 +297,13 @@ void DeviceConnection::updateNetworkInfomation(bool dhcp, const QString &ip, con void DeviceConnection::requestOta(const QString &file) { m_otaProgress = 0; emit otaProgressChanged(true, m_otaProgress, "正在向设备发起OTA请求......"); - - auto task = [this, file]() { + if (m_timerId > 0) { + killTimer(m_timerId); + m_timerId = -1; + } + Task task; + task.command = "a22devicefirmware_setdata"; + task.task = [this, file]() { std::ifstream ifs(Amass::StringUtility::UTF8ToGBK(file.toStdString()), std::ifstream::binary); m_uploadBuffer = std::vector((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); m_sendedSize = 0; @@ -296,7 +334,7 @@ void DeviceConnection::requestOta(const QString &file) { LOG(info) << "requestOta: " << text << ": " << text.size(); }; if (m_requests.empty()) { - task(); + task.task(); } m_requests.push(task); } @@ -343,12 +381,13 @@ void DeviceConnection::transferBinContent() { } } -void DeviceConnection::handleCommand(const std::string_view &replyText) { +QString DeviceConnection::handleCommand(const std::string_view &replyText) { + QString ret; boost::system::error_code error; auto replyValue = boost::json::parse(replyText, error); if (error) { LOG(error) << "prase [" << replyText << "] failed, message: " << error.message(); - return; + return ret; } auto &reply = replyValue.as_object(); auto &function = reply.at("func").as_string(); @@ -410,6 +449,13 @@ void DeviceConnection::handleCommand(const std::string_view &replyText) { m_networkInfomation.gateway = data.at("gateway").as_string().c_str(); m_networkInfomation.netmask = data.at("netmask").as_string().c_str(); emit networkInfomationChanged(m_networkInfomation); + } else if (function == "a15devicedetail_getdata") { + auto &data = reply.at("data").as_object(); + auto firmware = QString::fromStdString(std::string(data.at("linux04_firmware").as_string())); + if (m_infomation.firmwareVersion != firmware) { + m_infomation.firmwareVersion = firmware; + emit firmwareChanged(m_infomation.firmwareVersion); + } } else if (function == "a03opendoor5_setdata") { requestAntiClipArea(); } else if (function == "a03opendoor4_setdata") { @@ -442,18 +488,19 @@ void DeviceConnection::handleCommand(const std::string_view &replyText) { } else { LOG(warning) << "unknown reply: " << replyText; } + return QString::fromStdString(std::string(std::move(function))); } void DeviceConnection::onConnected() { - LOG(info) << "onConnected"; auto socket = dynamic_cast(sender()); if (socket == m_commandSocket) { + requestVersion(); requestOpenDoorArea(); requestShieldedArea(); requestAntiClipArea(); requestNetworkInfomation(); emit connected(); - // m_timerId = startTimer(2500); + m_timerId = startTimer(2500); if (m_otaProgress > 0) { m_otaProgress = 100; emit otaProgressChanged(true, m_otaProgress, "设备升级成功!"); @@ -465,6 +512,17 @@ void DeviceConnection::onConnected() { } } +void DeviceConnection::onDisconnected() { + auto socket = dynamic_cast(sender()); + if (socket == m_commandSocket) { + if (m_timerId > 0) { + killTimer(m_timerId); + m_timerId = -1; + } + emit disconnected(); + } +} + void DeviceConnection::setH264FrameCallback(H264FrameCallback &&callback) { m_frameCallback = std::move(callback); } @@ -497,13 +555,16 @@ void DeviceConnection::onCommandReadyRead() { while (!m_commandBuffer.isEmpty()) { auto packageSize = ntohl(*reinterpret_cast(m_commandBuffer.data())); if (m_commandBuffer.size() < (packageSize + sizeof(uint32_t))) break; - handleCommand(std::string_view(m_commandBuffer.data() + sizeof(uint32_t), packageSize)); + auto command = handleCommand(std::string_view(m_commandBuffer.data() + sizeof(uint32_t), packageSize)); m_commandBuffer.remove(0, packageSize + sizeof(uint32_t)); if (!m_requests.empty()) { - m_requests.pop(); + auto &task = m_requests.front(); + if (task.command == command) { + m_requests.pop(); + } if (!m_requests.empty()) { - m_requests.front()(); + m_requests.front().task(); } } } @@ -522,6 +583,14 @@ void DeviceConnection::onErrorOccurred(QAbstractSocket::SocketError socketError) void DeviceConnection::timerEvent(QTimerEvent *event) { if (isConnected()) { - requestOpenDoorArea(); + int index = heartbeats % 3; + if (index == 0) { + requestOpenDoorArea(); + } else if (index == 1) { + requestShieldedArea(); + } else if (index == 2) { + requestAntiClipArea(); + } + heartbeats++; } } diff --git a/DeviceConnection.h b/DeviceConnection.h index afb0d22..d351cc3 100644 --- a/DeviceConnection.h +++ b/DeviceConnection.h @@ -67,6 +67,7 @@ public: void requestResolution(Resolution resolution); void requestNetworkInfomation(); void updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway); + void requestVersion(); /** * @brief 对设备升级OTA,主要有几个步骤 @@ -86,13 +87,15 @@ signals: void shieldedAreaChanged(bool enabled, const QList &points); void antiClipAreaChanged(bool enabled, const QList &points); void networkInfomationChanged(const NetworkInfomation &info); + void firmwareChanged(const QString &firmware); void otaProgressChanged(bool status, int progress, const QString &message); protected: void onConnected(); + void onDisconnected(); void onH264ReadyRead(); void onCommandReadyRead(); - void handleCommand(const std::string_view &replyText); + QString handleCommand(const std::string_view &replyText); void onErrorOccurred(QAbstractSocket::SocketError socketError); void timerEvent(QTimerEvent *event) final; void transferBinContent(); @@ -113,10 +116,17 @@ private: int m_sendedSize = 0; H264FrameCallback m_frameCallback; - std::queue> m_requests; + class Task { + public: + QString command; + std::function task; + }; + std::queue m_requests; int m_timerId = -1; + int heartbeats = 0; Area m_area; NetworkInfomation m_networkInfomation; + QString m_firmware; }; #endif // DEVICECONNECTION_H diff --git a/DeviceListModel.cpp b/DeviceListModel.cpp index 0091d18..b1b38c1 100644 --- a/DeviceListModel.cpp +++ b/DeviceListModel.cpp @@ -146,9 +146,15 @@ void DeviceListModel::onDeviceReplyReadyRead() { auto replyVale = boost::json::parse(datagram.data().toStdString()); auto &reply = replyVale.as_object(); DeviceConnection::Infomation 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())); + if (reply.contains("devid")) { + device.deviceId = QString::fromStdString(std::string(reply.at("devid").as_string())); + } + if (reply.contains("fw_ver")) { + device.firmwareVersion = QString::fromStdString(std::string(reply.at("fw_ver").as_string())); + } + if (reply.contains("sw_ver")) { + 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(), diff --git a/main.cpp b/main.cpp index 5006378..87af86b 100644 --- a/main.cpp +++ b/main.cpp @@ -13,7 +13,7 @@ int main(int argc, char *argv[]) { LOG(info) << "Program version: " << APP_VERSION << std::endl; auto app = Singleton::instance(argc, argv); - QQuickStyle::setStyle("Basic"); + QQuickStyle::setStyle("Material"); return app->exec(); } diff --git a/qml/DeviceView.qml b/qml/DeviceView.qml index 7738d38..904a47d 100644 --- a/qml/DeviceView.qml +++ b/qml/DeviceView.qml @@ -245,7 +245,11 @@ Item { anchors.bottom: parent.bottom columns: 2 spacing: 10 - Text {text: qsTr("开门区域: ")} + verticalItemAlignment: Qt.AlignVCenter + Text { + + text: qsTr("开门区域: ") + } Row { enabled: root.enabled RadioButton { diff --git a/qml/IpTextField.qml b/qml/IpTextField.qml new file mode 100644 index 0000000..2d4ba4a --- /dev/null +++ b/qml/IpTextField.qml @@ -0,0 +1,34 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Column { + id: root + property alias text: input.text + property bool valid: false + TextField { + height: 36 + width: 350 + id: input + + onTextChanged: { + valid = validateIp(text); + if(!valid){ + hint.text="参数配置无效" + } else { + hint.text="" + } + } + } + Text { + id: hint + color: "red" + font.pixelSize: 12 + } + + function validateIp(ip) { + // Regular expression for validating IP address + var regex = /^(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])$/; + return regex.test(ip); + } +} diff --git a/qml/Main.qml b/qml/Main.qml index a29ef5b..1c4a60b 100644 --- a/qml/Main.qml +++ b/qml/Main.qml @@ -9,27 +9,25 @@ ApplicationWindow { width: 1000 height: 640 visible: true - title: qsTr("Hello World") + title: qsTr("T009上位机工具") header: ToolBar { RowLayout { anchors.fill: parent - Button { + ToolButton { text: "搜索设备" onClicked: { deviceList.currentIndex = -1 App.startSearchDevice() } } - Text { + Label { text: `设备总数: ${deviceList.count}` } - Text { + Label { Layout.alignment: Qt.AlignRight - Layout.preferredWidth: 400 - text: deviceList.currentIndex - >= 0 ? `当前设备版本号: ${App.devices.get( - deviceList.currentIndex).softwareVersion}` : "" + Layout.preferredWidth: 280 + text: App.currentFirmware.length > 0 ? `当前设备版本号: ${App.currentFirmware}` : "" } } } @@ -97,7 +95,7 @@ ApplicationWindow { anchors.bottom: parent.bottom anchors.left: deviceList.right anchors.right: parent.right - enabled: deviceList.currentIndex>=0 + enabled: deviceList.currentIndex >= 0 openDoorAreaWay: App.currentOpenDoorAreaWay openDoorAreaPoints: App.currentOpenDoorAreaPoints shieldedAreaEnabled: App.currentShieldedAreaEnabled @@ -110,7 +108,6 @@ ApplicationWindow { id: networkPopup visible: false width: 500 - height: 240 } OtaPopup { diff --git a/qml/MessageDialog.qml b/qml/MessageDialog.qml index 0e4d5ca..1df78bc 100644 --- a/qml/MessageDialog.qml +++ b/qml/MessageDialog.qml @@ -72,7 +72,7 @@ Dialog { Button { id: cancelButton width: 72 - height: 26 + height: 40 anchors.right: parent.right anchors.rightMargin: 15 anchors.bottom: parent.bottom diff --git a/qml/NetworkSettingPopup.qml b/qml/NetworkSettingPopup.qml index 8d8903b..2d918ea 100644 --- a/qml/NetworkSettingPopup.qml +++ b/qml/NetworkSettingPopup.qml @@ -1,116 +1,141 @@ import QtQuick import QtQuick.Controls +import QtQuick.Layouts import AntiClipSettings Popup { id: root parent: Overlay.overlay anchors.centerIn: Overlay.overlay + modal: true + property int inputHeight: 50 + background: Rectangle { + radius: 8 + } + contentItem: ColumnLayout { + anchors.centerIn: parent - Rectangle { - width: parent.width - height: parent.height - color: "white" - border.color: "lightgray" - radius: 10 - - Column { - anchors.centerIn: parent + Row { 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 - } + Label { + text: "模式" + width: 100 + anchors.verticalCenter: parent.verticalCenter } - Row { - spacing: 5 - - Text { - text: "设备IP" - font.pointSize: 14 - width: 100 - } - - TextField { - id: ipInput - width: 350 - height: 30 - text: App.currentNetworkInfomation.ip - } + RadioButton { + id: dhcpMode + text: "DHCP" + checked: App.currentNetworkInfomation.dhcp } - Row { - spacing: 5 - Text { - width: 100 - text: "子网掩码" - font.pointSize: 14 - } + RadioButton { + id: staticMode + text: "静态IP" + checked: true + // checked: !App.currentNetworkInfomation.dhcp + } + } - TextField { - id: netmaskInput - width: 350 - height: 30 - text: App.currentNetworkInfomation.netmask - } + Row { + spacing: 5 + visible: staticMode.checked + Label { + anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenterOffset: -10 + text: "设备IP" + width: 100 } - Row { - spacing: 5 + IpTextField { + id: ipInput + height: inputHeight + width: 350 + text: App.currentNetworkInfomation.ip + } + } - Row { - spacing: 5 - - Text { - text: "设备网关" - font.pointSize: 14 - width: 100 - } - } - - TextField { - id: gatewayInput - width: 350 - height: 30 - text: App.currentNetworkInfomation.gateway - } + Row { + spacing: 5 + visible: staticMode.checked + Label { + anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenterOffset: -10 + width: 100 + text: "子网掩码" } - Row { - spacing: 20 - anchors.horizontalCenter: parent.horizontalCenter + IpTextField { + id: netmaskInput + width: 350 + height: inputHeight + text: App.currentNetworkInfomation.netmask + } + } - Button { - text: "保存" - onClicked: { - App.updateNetworkInfomation(dhcpMode.checked,ipInput.text,netmaskInput.text,gatewayInput.text); + Row { + spacing: 5 + visible: staticMode.checked + Label { + anchors.verticalCenter: parent.verticalCenter + text: "设备网关" + anchors.verticalCenterOffset: -10 + width: 100 + } + + IpTextField { + id: gatewayInput + width: 350 + height: inputHeight + text: App.currentNetworkInfomation.gateway + } + } + + Row { + spacing: 5 + visible: staticMode.checked + Label { + anchors.verticalCenter: parent.verticalCenter + text: "DNS服务器" + anchors.verticalCenterOffset: -10 + width: 100 + } + + IpTextField { + id: dnsInput + width: 350 + height: inputHeight + text: App.currentNetworkInfomation.gateway + } + } + + Row { + Layout.rightMargin: 20 + Layout.alignment: Qt.AlignRight + spacing: 20 + + Button { + text: "保存" + onClicked: { + if (dhcpMode.checked || (staticMode.checked && ipInput.valid + && netmaskInput.valid + && gatewayInput.valid + && dnsInput.valid)) { + App.updateNetworkInfomation(dhcpMode.checked, + ipInput.text, + netmaskInput.text, + gatewayInput.text) networkPopup.close() + } else { + showMessageDialog(2, "网络设置", "请输入合法参数地址!") } } + } - Button { - text: "取消" - onClicked: root.close() - } + Button { + text: "取消" + onClicked: root.close() } } } diff --git a/qml/OtaPopup.qml b/qml/OtaPopup.qml index b0eb1ab..b72279b 100644 --- a/qml/OtaPopup.qml +++ b/qml/OtaPopup.qml @@ -14,6 +14,7 @@ Popup { modal: true focus: true closePolicy: Popup.CloseOnEscape + property bool otaFinished: true property var onClose ColumnLayout { @@ -23,9 +24,15 @@ Popup { RowLayout { Layout.alignment: Qt.AlignRight - Button { - text: "关闭" - onClicked: root.close() + IconButton { + source: "../resources/popup_close.svg" + onClicked: { + if(otaFinished){ + root.close() + }else{ + showMessageDialog(2,"OTA升级","设备正在升级中,请耐心等待...") + } + } } } @@ -34,7 +41,8 @@ Popup { TextField { id: otaFile Layout.fillWidth: true - placeholderText: "请选择升级文件或将文件拖入工具中" + readOnly: true + placeholderText: "请选择升级bin文件" } Button { text: "选择" @@ -99,6 +107,7 @@ Popup { Connections { target: App function onCurrentDeviceOtaProgressChanged (status, progress, message) { + otaFinished = !status || (progress>=100) progressBar.value = progress progressText.text = `${progress}%` if(progress>=100){ @@ -107,7 +116,6 @@ Popup { }else { otaMessage.text = message } - } } }