Compare commits
10 Commits
5445380824
...
42c5b7e4e1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42c5b7e4e1 | ||
|
|
18ec0257d7 | ||
|
|
61a27c6882 | ||
|
|
15bb1ce07d | ||
|
|
d049d9d908 | ||
|
|
29e3fa2900 | ||
|
|
faae203eb1 | ||
|
|
5bf62c410a | ||
|
|
3e90c5f980 | ||
|
|
6c7499efa4 |
@ -20,12 +20,14 @@ set(SOURCES
|
||||
src/mainwindow.cpp
|
||||
src/mqttclient.cpp
|
||||
src/lightstripmanager.cpp
|
||||
src/updatesettingsdialog.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
src/mainwindow.h
|
||||
src/mqttclient.h
|
||||
src/lightstripmanager.h
|
||||
src/updatesettingsdialog.h
|
||||
)
|
||||
|
||||
add_executable(QtDemo ${SOURCES} ${HEADERS}
|
||||
|
||||
@ -1,6 +1,14 @@
|
||||
#include "lightstripmanager.h"
|
||||
#include <QThread>
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
// 如果不再需要可以删除: #include <QRandomGenerator>
|
||||
|
||||
LightStripManager::LightStripManager(QWidget *parent)
|
||||
@ -11,6 +19,7 @@ LightStripManager::LightStripManager(QWidget *parent)
|
||||
{
|
||||
setupUI();
|
||||
loadSnList();
|
||||
loadBatteryInfo(); // 加载电量信息
|
||||
|
||||
// 设置窗口属性
|
||||
setWindowTitle("灯条SN管理器");
|
||||
@ -205,11 +214,42 @@ void LightStripManager::setupControlPanel()
|
||||
);
|
||||
connect(refreshBtn, &QPushButton::clicked, this, &LightStripManager::onRefreshClicked);
|
||||
|
||||
// 新增:备份按钮
|
||||
backupBtn = new QPushButton("备份灯条");
|
||||
backupBtn->setMinimumHeight(35);
|
||||
backupBtn->setStyleSheet(
|
||||
"QPushButton { "
|
||||
" background-color: #673AB7; "
|
||||
" color: white; "
|
||||
" font-weight: bold; "
|
||||
" border-radius: 6px; "
|
||||
" padding: 8px 16px; "
|
||||
"} "
|
||||
"QPushButton:hover { background-color: #5E35B1; }"
|
||||
);
|
||||
connect(backupBtn, &QPushButton::clicked, this, &LightStripManager::onBackupClicked);
|
||||
|
||||
// 恢复备份按钮
|
||||
restoreBtn = new QPushButton("恢复备份");
|
||||
restoreBtn->setStyleSheet(
|
||||
"QPushButton { "
|
||||
" background-color: #FF9800; "
|
||||
" color: white; "
|
||||
" font-weight: bold; "
|
||||
" border-radius: 6px; "
|
||||
" padding: 8px 16px; "
|
||||
"} "
|
||||
"QPushButton:hover { background-color: #F57C00; }"
|
||||
);
|
||||
connect(restoreBtn, &QPushButton::clicked, this, &LightStripManager::onRestoreClicked);
|
||||
|
||||
row1Layout->addWidget(selectAllBtn);
|
||||
row1Layout->addWidget(deselectAllBtn);
|
||||
row1Layout->addWidget(deleteSelectedBtn);
|
||||
row1Layout->addWidget(clearAllBtn);
|
||||
row1Layout->addWidget(refreshBtn);
|
||||
row1Layout->addWidget(backupBtn);
|
||||
row1Layout->addWidget(restoreBtn);
|
||||
row1Layout->addStretch();
|
||||
|
||||
// 统计标签
|
||||
@ -452,6 +492,7 @@ void LightStripManager::setupLightControlArea()
|
||||
connect(sendLightSelectedBtn, &QPushButton::clicked, this, &LightStripManager::onSendLightSelectedClicked);
|
||||
row2Layout->addWidget(sendLightSelectedBtn);
|
||||
|
||||
/*
|
||||
sendLightAllBtn = new QPushButton("点亮全部");
|
||||
sendLightAllBtn->setMinimumHeight(40);
|
||||
sendLightAllBtn->setMinimumWidth(120);
|
||||
@ -468,24 +509,7 @@ void LightStripManager::setupLightControlArea()
|
||||
);
|
||||
connect(sendLightAllBtn, &QPushButton::clicked, this, &LightStripManager::onSendLightAllClicked);
|
||||
row2Layout->addWidget(sendLightAllBtn);
|
||||
|
||||
// 新增:分组点亮按钮
|
||||
groupLightBtn = new QPushButton("分组点亮");
|
||||
groupLightBtn->setMinimumHeight(40);
|
||||
groupLightBtn->setMinimumWidth(120);
|
||||
groupLightBtn->setStyleSheet(
|
||||
"QPushButton { "
|
||||
" background-color: #9C27B0; "
|
||||
" color: white; "
|
||||
" font-weight: bold; "
|
||||
" padding: 10px 20px; "
|
||||
" border-radius: 6px; "
|
||||
" font-size: 14px; "
|
||||
"} "
|
||||
"QPushButton:hover { background-color: #7B1FA2; }"
|
||||
);
|
||||
connect(groupLightBtn, &QPushButton::clicked, this, &LightStripManager::onGroupLightClicked);
|
||||
row2Layout->addWidget(groupLightBtn);
|
||||
*/
|
||||
|
||||
lightControlLayout->addLayout(row2Layout);
|
||||
|
||||
@ -543,20 +567,31 @@ QWidget* LightStripManager::createSnWidget(const QString &sn)
|
||||
"QCheckBox { "
|
||||
" font-weight: bold; "
|
||||
" font-size: 12px; "
|
||||
" spacing: 8px; "
|
||||
"} "
|
||||
"QCheckBox::indicator { "
|
||||
" width: 20px; "
|
||||
" height: 20px; "
|
||||
" width: 18px; "
|
||||
" height: 18px; "
|
||||
" border-radius: 9px; "
|
||||
" border: 2px solid #d0d0d0; "
|
||||
" background-color: #ffffff; "
|
||||
"} "
|
||||
"QCheckBox::indicator:unchecked { "
|
||||
" border: 2px solid #ccc; "
|
||||
" border-radius: 4px; "
|
||||
" background-color: white; "
|
||||
"QCheckBox::indicator:unchecked:hover { "
|
||||
" border: 2px solid #4CAF50; "
|
||||
" background-color: #f0f8f0; "
|
||||
"} "
|
||||
"QCheckBox::indicator:checked { "
|
||||
" border: 2px solid #4CAF50; "
|
||||
" border-radius: 4px; "
|
||||
" background-color: #4CAF50; "
|
||||
"} "
|
||||
"QCheckBox::indicator:checked:hover { "
|
||||
" background-color: #66BB6A; "
|
||||
"} "
|
||||
"QCheckBox::indicator:checked::after { "
|
||||
" content: '✓'; "
|
||||
" color: white; "
|
||||
" font-size: 12px; "
|
||||
" font-weight: bold; "
|
||||
"}"
|
||||
);
|
||||
connect(checkBox, &QCheckBox::stateChanged, this, &LightStripManager::onCheckBoxStateChanged);
|
||||
@ -580,9 +615,33 @@ QWidget* LightStripManager::createSnWidget(const QString &sn)
|
||||
);
|
||||
snLabel->setWordWrap(true);
|
||||
|
||||
// 创建电量标签
|
||||
QLabel *batteryLabel = new QLabel("电量: --");
|
||||
batteryLabel->setAlignment(Qt::AlignCenter);
|
||||
batteryLabel->setStyleSheet(
|
||||
"QLabel { "
|
||||
" color: #666; "
|
||||
" font-size: 10px; "
|
||||
" background-color: #f5f5f5; "
|
||||
" border: 1px solid #ddd; "
|
||||
" border-radius: 3px; "
|
||||
" padding: 2px 4px; "
|
||||
" min-height: 8px; "
|
||||
"}"
|
||||
);
|
||||
|
||||
// 存储电量标签的引用
|
||||
batteryLabels[sn] = batteryLabel;
|
||||
|
||||
// 如果已有电量信息,则显示并设置正确颜色
|
||||
if (batteryInfoMap.contains(sn)) {
|
||||
updateBatteryInfo(sn, batteryInfoMap[sn]);
|
||||
}
|
||||
|
||||
// 添加到布局
|
||||
itemLayout->addWidget(checkBox, 0, Qt::AlignCenter);
|
||||
itemLayout->addWidget(snLabel);
|
||||
itemLayout->addWidget(batteryLabel);
|
||||
itemLayout->addStretch();
|
||||
|
||||
return lightStripWidget;
|
||||
@ -660,12 +719,17 @@ void LightStripManager::onClearSnListClicked()
|
||||
lightStripCheckBoxes.clear();
|
||||
uniqueSnSet.clear();
|
||||
|
||||
// 清空电量相关数据
|
||||
batteryInfoMap.clear();
|
||||
batteryLabels.clear();
|
||||
|
||||
// 更新显示
|
||||
updateSnCount();
|
||||
updateControlButtons();
|
||||
|
||||
// 保存设置
|
||||
saveSnList();
|
||||
saveBatteryInfo(); // 保存电量信息
|
||||
|
||||
emit clearAllRequested();
|
||||
}
|
||||
@ -751,7 +815,12 @@ void LightStripManager::onDeleteSelectedClicked()
|
||||
// 从集合中移除SN
|
||||
QLabel *snLabel = lightStripWidgets[i]->findChild<QLabel*>();
|
||||
if (snLabel) {
|
||||
uniqueSnSet.remove(snLabel->text());
|
||||
QString sn = snLabel->text();
|
||||
uniqueSnSet.remove(sn);
|
||||
|
||||
// 清理电量相关数据
|
||||
batteryInfoMap.remove(sn);
|
||||
batteryLabels.remove(sn);
|
||||
}
|
||||
|
||||
// 删除widget
|
||||
@ -861,6 +930,147 @@ void LightStripManager::onAddSnManuallyClicked()
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
void LightStripManager::onRestoreClicked()
|
||||
{
|
||||
QString backupDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/backups";
|
||||
|
||||
// 打开文件选择对话框
|
||||
QString filePath = QFileDialog::getOpenFileName(
|
||||
this,
|
||||
"选择要恢复的备份文件",
|
||||
backupDir,
|
||||
"JSON备份文件 (*.json);;所有文件 (*)"
|
||||
);
|
||||
|
||||
if (filePath.isEmpty()) {
|
||||
return; // 用户取消了选择
|
||||
}
|
||||
|
||||
// 加载备份文件
|
||||
if (loadBackupFile(filePath)) {
|
||||
// 恢复成功,刷新显示
|
||||
applyResponsiveLayout();
|
||||
updateSnCount();
|
||||
updateControlButtons();
|
||||
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("恢复完成");
|
||||
msgBox.setText("备份文件已成功恢复!");
|
||||
msgBox.setIcon(QMessageBox::Information);
|
||||
msgBox.setStyleSheet(
|
||||
"QMessageBox { "
|
||||
" color: #000000; "
|
||||
"} "
|
||||
"QPushButton { "
|
||||
" color: #000000; "
|
||||
" background-color: #f0f0f0; "
|
||||
" border: 1px solid #ccc; "
|
||||
" border-radius: 4px; "
|
||||
" padding: 6px 12px; "
|
||||
" min-width: 60px; "
|
||||
"} "
|
||||
"QPushButton:hover { "
|
||||
" background-color: #e0e0e0; "
|
||||
"}"
|
||||
);
|
||||
msgBox.exec();
|
||||
} else {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("恢复失败");
|
||||
msgBox.setText("无法读取或解析备份文件,请检查文件格式是否正确。");
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setStyleSheet(
|
||||
"QMessageBox { "
|
||||
" color: #000000; "
|
||||
"} "
|
||||
"QPushButton { "
|
||||
" color: #000000; "
|
||||
" background-color: #f0f0f0; "
|
||||
" border: 1px solid #ccc; "
|
||||
" border-radius: 4px; "
|
||||
" padding: 6px 12px; "
|
||||
" min-width: 60px; "
|
||||
"} "
|
||||
"QPushButton:hover { "
|
||||
" background-color: #e0e0e0; "
|
||||
"}"
|
||||
);
|
||||
msgBox.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void LightStripManager::onBackupClicked()
|
||||
{
|
||||
if (uniqueSnSet.isEmpty()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("提示");
|
||||
msgBox.setText("当前没有灯条SN数据,无需备份。");
|
||||
msgBox.setIcon(QMessageBox::Information);
|
||||
msgBox.setStyleSheet(
|
||||
"QMessageBox { "
|
||||
" color: #000000; "
|
||||
"} "
|
||||
"QPushButton { "
|
||||
" color: #000000; "
|
||||
" background-color: #f0f0f0; "
|
||||
" border: 1px solid #ccc; "
|
||||
" border-radius: 4px; "
|
||||
" padding: 6px 12px; "
|
||||
" min-width: 60px; "
|
||||
"} "
|
||||
"QPushButton:hover { "
|
||||
" background-color: #e0e0e0; "
|
||||
"}"
|
||||
);
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
// 弹出输入框,支持自定义备份文件名
|
||||
bool ok = false;
|
||||
QString inputName = QInputDialog::getText(
|
||||
this,
|
||||
"输入备份文件名",
|
||||
"备份文件名(可留空自动生成):",
|
||||
QLineEdit::Normal,
|
||||
"",
|
||||
&ok
|
||||
);
|
||||
if (!ok) {
|
||||
return; // 用户取消
|
||||
}
|
||||
|
||||
// 执行备份:使用用户输入或自动生成的文件名
|
||||
if (inputName.trimmed().isEmpty()) {
|
||||
backupSnList();
|
||||
} else {
|
||||
createBackupFile(inputName.trimmed());
|
||||
}
|
||||
|
||||
// 显示备份成功消息
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle("备份完成");
|
||||
msgBox.setText(QString("已成功备份 %1 个灯条SN。\n备份文件保存在应用数据目录的backups文件夹中。").arg(uniqueSnSet.size()));
|
||||
msgBox.setIcon(QMessageBox::Information);
|
||||
msgBox.setStyleSheet(
|
||||
"QMessageBox { "
|
||||
" color: #000000; "
|
||||
"} "
|
||||
"QPushButton { "
|
||||
" color: #000000; "
|
||||
" background-color: #f0f0f0; "
|
||||
" border: 1px solid #ccc; "
|
||||
" border-radius: 4px; "
|
||||
" padding: 6px 12px; "
|
||||
" min-width: 60px; "
|
||||
"} "
|
||||
"QPushButton:hover { "
|
||||
" background-color: #e0e0e0; "
|
||||
"}"
|
||||
);
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
void LightStripManager::onSearchTextChanged(const QString &text)
|
||||
{
|
||||
filterSnDisplay(text);
|
||||
@ -1099,7 +1309,7 @@ void LightStripManager::updateControlButtons()
|
||||
|
||||
deleteSelectedBtn->setEnabled(selectedCount > 0);
|
||||
sendLightSelectedBtn->setEnabled(selectedCount > 0);
|
||||
sendLightAllBtn->setEnabled(totalCount > 0);
|
||||
//sendLightAllBtn->setEnabled(totalCount > 0);
|
||||
clearAllBtn->setEnabled(totalCount > 0);
|
||||
selectAllBtn->setEnabled(totalCount > 0);
|
||||
deselectAllBtn->setEnabled(selectedCount > 0);
|
||||
@ -1140,6 +1350,9 @@ void LightStripManager::saveSnList()
|
||||
QStringList snList = uniqueSnSet.values();
|
||||
settings->setValue("lightStripSnList", snList);
|
||||
qDebug() << "已保存" << snList.size() << "个SN到lightStripSnList";
|
||||
|
||||
// 注释掉自动备份功能
|
||||
// backupSnList();
|
||||
}
|
||||
|
||||
// 强制同步到磁盘
|
||||
@ -1479,6 +1692,9 @@ void LightStripManager::syncSnListFromMainWindow(const QStringList &snList)
|
||||
lightStripCheckBoxes.clear();
|
||||
uniqueSnSet.clear();
|
||||
|
||||
// 清理电量标签映射(但保留电量信息数据)
|
||||
batteryLabels.clear();
|
||||
|
||||
// 批量添加但不保存
|
||||
for (const QString &sn : snList) {
|
||||
if (!uniqueSnSet.contains(sn)) {
|
||||
@ -1498,7 +1714,7 @@ void LightStripManager::syncSnListFromMainWindow(const QStringList &snList)
|
||||
|
||||
void LightStripManager::setupIdentityBindingArea()
|
||||
{
|
||||
identityBindingGroup = new QGroupBox("身份信息绑定", this);
|
||||
identityBindingGroup = new QGroupBox("身份信息绑定(未满10个下发绑定后需等1分钟,或继续补充满10个立即触发)", this);
|
||||
identityBindingGroup->setStyleSheet(
|
||||
"QGroupBox { "
|
||||
" color: #000000; "
|
||||
@ -1716,6 +1932,24 @@ void LightStripManager::setupIdentityBindingArea()
|
||||
row2Layout->addWidget(bindIdentityAllBtn);
|
||||
|
||||
row2Layout->addStretch();
|
||||
|
||||
// 新增:分组点亮按钮
|
||||
groupLightBtn = new QPushButton("分组绑定点亮");
|
||||
groupLightBtn->setMinimumHeight(40);
|
||||
groupLightBtn->setMinimumWidth(120);
|
||||
groupLightBtn->setStyleSheet(
|
||||
"QPushButton { "
|
||||
" background-color: #9C27B0; "
|
||||
" color: white; "
|
||||
" font-weight: bold; "
|
||||
" padding: 10px 20px; "
|
||||
" border-radius: 6px; "
|
||||
" font-size: 14px; "
|
||||
"} "
|
||||
"QPushButton:hover { background-color: #7B1FA2; }"
|
||||
);
|
||||
connect(groupLightBtn, &QPushButton::clicked, this, &LightStripManager::onGroupLightClicked);
|
||||
row2Layout->addWidget(groupLightBtn);
|
||||
|
||||
bindingStatusLabel = new QLabel("状态: 就绪");
|
||||
bindingStatusLabel->setStyleSheet(
|
||||
@ -1734,4 +1968,328 @@ void LightStripManager::setupIdentityBindingArea()
|
||||
|
||||
// 加载保存的身份信息设置
|
||||
loadIdentitySettings();
|
||||
}
|
||||
|
||||
// 电量信息管理方法实现
|
||||
void LightStripManager::updateBatteryInfo(const QString &sn, const QString &batteryLevel)
|
||||
{
|
||||
batteryInfoMap[sn] = batteryLevel;
|
||||
|
||||
// 添加调试信息
|
||||
qDebug() << "[DEBUG] 更新电量信息 - SN:" << sn << "电量:" << batteryLevel;
|
||||
|
||||
// 更新对应的电量标签
|
||||
if (batteryLabels.contains(sn)) {
|
||||
batteryLabels[sn]->setText(QString("电量: %1").arg(batteryLevel));
|
||||
|
||||
// 根据电量设置不同颜色
|
||||
QString color = "#666";
|
||||
QString bgColor = "#fff3cd";
|
||||
QString borderColor = "#ffeaa7";
|
||||
|
||||
bool ok;
|
||||
int level = batteryLevel.toInt(&ok);
|
||||
qDebug() << "[DEBUG] 电量转换 - 原值:" << batteryLevel << "转换后:" << level << "转换成功:" << ok;
|
||||
|
||||
if (ok) {
|
||||
// 判断电量值是毫伏值还是百分比
|
||||
if (level > 100) {
|
||||
qDebug() << "[DEBUG] 检测为毫伏值:" << level;
|
||||
// 毫伏值,一般锂电池范围 2500-4200mV
|
||||
if (level < 2600) { // 低电量 (<2.8V)
|
||||
color = "#d32f2f";
|
||||
bgColor = "#ffebee";
|
||||
borderColor = "#f8bbd9";
|
||||
qDebug() << "[DEBUG] 设置为红色 - 低电量";
|
||||
} else if (level < 2900) { // 中等电量 (2.8V-2.9V)
|
||||
color = "#f57c00";
|
||||
bgColor = "#fff3e0";
|
||||
borderColor = "#ffcc02";
|
||||
qDebug() << "[DEBUG] 设置为黄色 - 中等电量";
|
||||
} else { // 健康电量 (≥2.9V)
|
||||
color = "#388e3c";
|
||||
bgColor = "#e8f5e8";
|
||||
borderColor = "#4caf50";
|
||||
qDebug() << "[DEBUG] 设置为绿色 - 健康电量";
|
||||
}
|
||||
} else {
|
||||
// 百分比值 (0-100)
|
||||
if (level <= 20) {
|
||||
color = "#d32f2f";
|
||||
bgColor = "#ffebee";
|
||||
borderColor = "#f8bbd9";
|
||||
} else if (level <= 50) {
|
||||
color = "#f57c00";
|
||||
bgColor = "#fff3e0";
|
||||
borderColor = "#ffcc02";
|
||||
} else {
|
||||
color = "#388e3c";
|
||||
bgColor = "#e8f5e8";
|
||||
borderColor = "#4caf50";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
batteryLabels[sn]->setStyleSheet(
|
||||
QString("QLabel { "
|
||||
" color: %1; "
|
||||
" font-size: 10px; "
|
||||
" background-color: %2; "
|
||||
" border: 1px solid %3; "
|
||||
" border-radius: 3px; "
|
||||
" padding: 2px 4px; "
|
||||
" min-height: 8px; "
|
||||
"}").arg(color, bgColor, borderColor)
|
||||
);
|
||||
}
|
||||
|
||||
// 保存电量信息
|
||||
saveBatteryInfo();
|
||||
}
|
||||
|
||||
void LightStripManager::saveBatteryInfo()
|
||||
{
|
||||
settings->beginGroup("BatteryInfo");
|
||||
settings->remove(""); // 清空组内所有键
|
||||
|
||||
for (auto it = batteryInfoMap.begin(); it != batteryInfoMap.end(); ++it) {
|
||||
settings->setValue(it.key(), it.value());
|
||||
}
|
||||
|
||||
settings->endGroup();
|
||||
settings->sync();
|
||||
|
||||
qDebug() << "保存电量信息,共" << batteryInfoMap.size() << "条记录";
|
||||
}
|
||||
|
||||
void LightStripManager::loadBatteryInfo()
|
||||
{
|
||||
batteryInfoMap.clear();
|
||||
|
||||
settings->beginGroup("BatteryInfo");
|
||||
QStringList keys = settings->allKeys();
|
||||
|
||||
for (const QString &key : keys) {
|
||||
QString value = settings->value(key).toString();
|
||||
batteryInfoMap[key] = value;
|
||||
|
||||
// 如果对应的电量标签存在,更新显示和颜色
|
||||
if (batteryLabels.contains(key)) {
|
||||
updateBatteryInfo(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
settings->endGroup();
|
||||
|
||||
qDebug() << "加载电量信息,共" << batteryInfoMap.size() << "条记录";
|
||||
}
|
||||
|
||||
// 新增:SN列表备份功能实现
|
||||
void LightStripManager::backupSnList()
|
||||
{
|
||||
if (uniqueSnSet.isEmpty()) {
|
||||
qDebug() << "SN列表为空,无需备份";
|
||||
return;
|
||||
}
|
||||
|
||||
createBackupFile();
|
||||
}
|
||||
|
||||
void LightStripManager::createBackupFile()
|
||||
{
|
||||
QString backupFileName = generateBackupFileName();
|
||||
QString backupDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/backups";
|
||||
|
||||
// 创建备份目录
|
||||
QDir dir;
|
||||
if (!dir.exists(backupDir)) {
|
||||
if (!dir.mkpath(backupDir)) {
|
||||
qDebug() << "创建备份目录失败:" << backupDir;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QString backupFilePath = backupDir + "/" + backupFileName;
|
||||
|
||||
// 创建备份文件内容
|
||||
QJsonObject backupData;
|
||||
backupData["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
|
||||
backupData["version"] = "1.0";
|
||||
backupData["count"] = uniqueSnSet.size();
|
||||
|
||||
QJsonArray snArray;
|
||||
QStringList snList = uniqueSnSet.values();
|
||||
for (const QString &sn : snList) {
|
||||
QJsonObject snObject;
|
||||
snObject["sn"] = sn;
|
||||
// 如果有电量信息,也一并备份
|
||||
if (batteryInfoMap.contains(sn)) {
|
||||
snObject["battery"] = batteryInfoMap[sn];
|
||||
}
|
||||
snArray.append(snObject);
|
||||
}
|
||||
backupData["lightstrips"] = snArray;
|
||||
|
||||
// 写入文件
|
||||
QJsonDocument doc(backupData);
|
||||
QFile file(backupFilePath);
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
file.write(doc.toJson());
|
||||
file.close();
|
||||
qDebug() << "SN列表备份成功:" << backupFilePath;
|
||||
qDebug() << "备份了" << uniqueSnSet.size() << "个灯条SN";
|
||||
} else {
|
||||
qDebug() << "创建备份文件失败:" << backupFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
QString LightStripManager::generateBackupFileName() const
|
||||
{
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QString timestamp = now.toString("yyyyMMdd_hhmmss");
|
||||
return QString("lightstrip_sn_backup_%1.json").arg(timestamp);
|
||||
}
|
||||
|
||||
void LightStripManager::createBackupFile(const QString &fileName)
|
||||
{
|
||||
QString backupDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/backups";
|
||||
|
||||
// 创建备份目录
|
||||
QDir dir;
|
||||
if (!dir.exists(backupDir)) {
|
||||
if (!dir.mkpath(backupDir)) {
|
||||
qDebug() << "创建备份目录失败:" << backupDir;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QString finalFileName = fileName;
|
||||
if (finalFileName.trimmed().isEmpty()) {
|
||||
finalFileName = generateBackupFileName();
|
||||
}
|
||||
if (!finalFileName.endsWith(".json", Qt::CaseInsensitive)) {
|
||||
finalFileName += ".json";
|
||||
}
|
||||
QString backupFilePath = backupDir + "/" + finalFileName;
|
||||
|
||||
// 若文件已存在,弹出确认是否覆盖
|
||||
QFileInfo fi(backupFilePath);
|
||||
if (fi.exists()) {
|
||||
QMessageBox::StandardButton reply = QMessageBox::question(
|
||||
this,
|
||||
"文件已存在",
|
||||
QString("备份文件 %1 已存在,是否覆盖?").arg(finalFileName),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
QMessageBox::No
|
||||
);
|
||||
if (reply != QMessageBox::Yes) {
|
||||
qDebug() << "用户取消覆盖,备份中止";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建备份文件内容
|
||||
QJsonObject backupData;
|
||||
backupData["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate);
|
||||
backupData["version"] = "1.0";
|
||||
backupData["count"] = uniqueSnSet.size();
|
||||
|
||||
QJsonArray snArray;
|
||||
QStringList snList = uniqueSnSet.values();
|
||||
for (const QString &sn : snList) {
|
||||
QJsonObject snObject;
|
||||
snObject["sn"] = sn;
|
||||
// 如果有电量信息,也一并备份
|
||||
if (batteryInfoMap.contains(sn)) {
|
||||
snObject["battery"] = batteryInfoMap[sn];
|
||||
}
|
||||
snArray.append(snObject);
|
||||
}
|
||||
backupData["lightstrips"] = snArray;
|
||||
|
||||
// 写入文件
|
||||
QJsonDocument doc(backupData);
|
||||
QFile file(backupFilePath);
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
file.write(doc.toJson());
|
||||
file.close();
|
||||
qDebug() << "SN列表备份成功:" << backupFilePath;
|
||||
qDebug() << "备份了" << uniqueSnSet.size() << "个灯条SN";
|
||||
} else {
|
||||
qDebug() << "创建备份文件失败:" << backupFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:SN列表恢复功能实现
|
||||
void LightStripManager::restoreSnList()
|
||||
{
|
||||
QString backupDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/backups";
|
||||
|
||||
// 打开文件选择对话框
|
||||
QString filePath = QFileDialog::getOpenFileName(
|
||||
this,
|
||||
"选择要恢复的备份文件",
|
||||
backupDir,
|
||||
"JSON备份文件 (*.json);;所有文件 (*)"
|
||||
);
|
||||
|
||||
if (!filePath.isEmpty()) {
|
||||
loadBackupFile(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
bool LightStripManager::loadBackupFile(const QString &filePath)
|
||||
{
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qDebug() << "无法打开备份文件:" << filePath;
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data = file.readAll();
|
||||
file.close();
|
||||
|
||||
QJsonParseError error;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(data, &error);
|
||||
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qDebug() << "解析JSON文件失败:" << error.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject backupData = doc.object();
|
||||
|
||||
// 验证文件格式
|
||||
if (!backupData.contains("lightstrips") || !backupData["lightstrips"].isArray()) {
|
||||
qDebug() << "备份文件格式不正确,缺少lightstrips数组";
|
||||
return false;
|
||||
}
|
||||
|
||||
// 清空当前数据
|
||||
uniqueSnSet.clear();
|
||||
batteryInfoMap.clear();
|
||||
|
||||
// 恢复SN列表和电量信息
|
||||
QJsonArray snArray = backupData["lightstrips"].toArray();
|
||||
for (const QJsonValue &value : snArray) {
|
||||
QJsonObject snObject = value.toObject();
|
||||
if (snObject.contains("sn")) {
|
||||
QString sn = snObject["sn"].toString();
|
||||
uniqueSnSet.insert(sn);
|
||||
|
||||
// 如果有电量信息,也一并恢复
|
||||
if (snObject.contains("battery")) {
|
||||
batteryInfoMap[sn] = snObject["battery"].toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 保存恢复的数据
|
||||
saveSnList();
|
||||
saveBatteryInfo();
|
||||
|
||||
qDebug() << "从备份文件恢复了" << uniqueSnSet.size() << "个灯条SN";
|
||||
qDebug() << "恢复了" << batteryInfoMap.size() << "条电量信息";
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -47,6 +47,11 @@ public:
|
||||
|
||||
// 新增:设置主窗口引用
|
||||
void setMainWindow(MainWindow *mainWindow);
|
||||
|
||||
// 新增:电量信息管理方法
|
||||
void updateBatteryInfo(const QString &sn, const QString &batteryLevel);
|
||||
void saveBatteryInfo();
|
||||
void loadBatteryInfo();
|
||||
|
||||
signals:
|
||||
void snSelectionChanged(const QStringList &selectedSns);
|
||||
@ -71,6 +76,8 @@ private slots:
|
||||
void onSendLightAllClicked();
|
||||
void onCheckBoxStateChanged();
|
||||
void onRefreshClicked();
|
||||
void onBackupClicked(); // 新增:备份按钮槽函数
|
||||
void onRestoreClicked(); // 新增:恢复备份按钮槽函数
|
||||
|
||||
// 新增:身份信息绑定相关槽函数
|
||||
void onBindIdentitySelectedClicked();
|
||||
@ -97,6 +104,16 @@ private:
|
||||
QWidget* createSnWidget(const QString &sn);
|
||||
void applyResponsiveLayout();
|
||||
|
||||
// 新增:SN列表备份功能
|
||||
void backupSnList();
|
||||
void createBackupFile();
|
||||
void createBackupFile(const QString &fileName);
|
||||
QString generateBackupFileName() const;
|
||||
|
||||
// 新增:SN列表恢复功能
|
||||
void restoreSnList();
|
||||
bool loadBackupFile(const QString &filePath);
|
||||
|
||||
// 新增:MQTT发送功能
|
||||
void sendLightControlMessage(const QStringList &sns);
|
||||
|
||||
@ -122,6 +139,8 @@ private:
|
||||
QPushButton *deleteSelectedBtn;
|
||||
QPushButton *clearAllBtn;
|
||||
QPushButton *refreshBtn;
|
||||
QPushButton *backupBtn; // 新增:备份按钮
|
||||
QPushButton *restoreBtn; // 新增:恢复备份按钮
|
||||
QLineEdit *searchEdit;
|
||||
QLineEdit *manualSnEdit;
|
||||
QPushButton *addSnBtn;
|
||||
@ -175,6 +194,10 @@ private:
|
||||
QString currentLabel1;
|
||||
QString currentLabel2;
|
||||
QString currentLabel3;
|
||||
|
||||
// 新增:电量信息相关数据
|
||||
QMap<QString, QString> batteryInfoMap; // SN -> 电量信息的映射
|
||||
QMap<QString, QLabel*> batteryLabels; // SN -> 电量标签的映射
|
||||
public:
|
||||
enum MatchRule {
|
||||
EQUAL = 0, // = (00)
|
||||
|
||||
1315
src/mainwindow.cpp
1315
src/mainwindow.cpp
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,12 @@
|
||||
#include <QGuiApplication>
|
||||
#include "mqttclient.h"
|
||||
#include "lightstripmanager.h"
|
||||
#include <QMenuBar>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
#include <QMessageBox>
|
||||
#include <QApplication> // 新增:用于获取系统调色板
|
||||
#include <QPalette>
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
@ -37,48 +43,59 @@ class MainWindow : public QMainWindow
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
// 新增:公共接口
|
||||
QString getDeviceSn() const;
|
||||
bool isMqttConnected() const;
|
||||
void publishMqttMessage(const QString &topic, const QString &message);
|
||||
|
||||
private slots:
|
||||
void showAbout(); // 简化为关于对话框
|
||||
void showUseGuide(); // 新增:使用说明对话框
|
||||
// MQTT相关槽函数
|
||||
void onConnectClicked();
|
||||
void onDisconnectClicked();
|
||||
void onSendLightAllClicked();
|
||||
void onMessageReceived(const QString &topic, const QString &message);
|
||||
void onMqttConnected();
|
||||
void onMqttDisconnected();
|
||||
void onMqttError(const QString &error);
|
||||
|
||||
// OTA相关槽函数
|
||||
void onMessageReceived(const QString &topic, const QString &message);
|
||||
void onOtaUpgradeClicked();
|
||||
void onOtaDowngradeClicked();
|
||||
void onGetVersionClicked();
|
||||
|
||||
// 灯条SN管理相关槽函数
|
||||
void onClearSnListClicked();
|
||||
void onSearchLightStripClicked();
|
||||
void openLightStripManager(); // 新增:打开灯条管理器
|
||||
void onLightStripManagerClosed(); // 新增:灯条管理器关闭时的处理
|
||||
void onGetVersionClicked();
|
||||
void onClearSnListClicked();
|
||||
void onLightStripManagerClosed();
|
||||
void onDeviceSnChanged(); // 新增:设备SN变化槽函数
|
||||
|
||||
// 更新相关槽函数
|
||||
void checkForUpdates();
|
||||
void onUpdateCheckFinished();
|
||||
void onUpdateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
|
||||
void onUpdateDownloadFinished();
|
||||
void onUpdateSettingsClicked();
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
void setupMenuBar();
|
||||
void setupToolBar();
|
||||
void createMenus(); // 重命名为更清晰的函数名
|
||||
void updateConnectionStatus(bool connected);
|
||||
void resubscribeTopics(); // 添加这个声明
|
||||
void processOtaMessage(const QJsonObject &otaData);
|
||||
void sendOtaCommand(const QString &version, bool isUpgrade = true);
|
||||
|
||||
// 灯条SN管理相关函数
|
||||
void processLightReportMessage(const QString &message);
|
||||
void addSnToList(const QString &sn);
|
||||
void saveSnList();
|
||||
void loadSnList();
|
||||
void sendSearchLightStripCommand();
|
||||
void openLightStripManager(); // 添加这个声明
|
||||
|
||||
// 更新相关函数
|
||||
void showUpdateDialog(const QString &version, const QString &downloadUrl, const QString &changelog);
|
||||
void downloadUpdate(const QString &downloadUrl);
|
||||
void installUpdate();
|
||||
int compareVersions(const QString &version1, const QString &version2);
|
||||
|
||||
// 新增:公共接口
|
||||
QString getDeviceSn() const;
|
||||
QString getTextColorForTheme() const;
|
||||
bool isMqttConnected() const;
|
||||
void publishMqttMessage(const QString &topic, const QString &message);
|
||||
|
||||
// 添加OTA状态跟踪
|
||||
bool otaOperationPending;
|
||||
QString pendingOtaVersion;
|
||||
@ -101,7 +118,7 @@ private:
|
||||
QGroupBox *deviceGroup;
|
||||
QLineEdit *deviceSnEdit;
|
||||
|
||||
// 点亮参数控制区域
|
||||
// 灯光控制区域
|
||||
QGroupBox *lightGroup;
|
||||
QComboBox *colorCombo;
|
||||
QComboBox *flashCombo;
|
||||
@ -110,7 +127,7 @@ private:
|
||||
QComboBox *soundCombo;
|
||||
QPushButton *sendLightAllBtn;
|
||||
|
||||
// 灯条SN管理区域 - 修改为横向布局
|
||||
// SN管理区域
|
||||
QGroupBox *snGroup;
|
||||
QScrollArea *snScrollArea; // 添加滚动区域
|
||||
QWidget *snContainerWidget; // 添加容器widget
|
||||
@ -119,7 +136,7 @@ private:
|
||||
QPushButton *clearSnBtn;
|
||||
QPushButton *searchLightStripBtn;
|
||||
|
||||
// OTA升级区域 - 添加缺失的成员变量
|
||||
// OTA升级区域
|
||||
QGroupBox *otaGroup;
|
||||
QLineEdit *currentVersionEdit;
|
||||
QPushButton *getVersionBtn;
|
||||
@ -128,17 +145,25 @@ private:
|
||||
QProgressBar *otaProgressBar;
|
||||
QLabel *otaStatusLabel;
|
||||
|
||||
// 消息显示区域 - 添加缺失的成员变量
|
||||
// 消息显示区域
|
||||
QGroupBox *messageGroup;
|
||||
QTextEdit *messageDisplay;
|
||||
|
||||
// 状态栏 - 添加缺失的成员变量
|
||||
// 状态栏
|
||||
QLabel *statusLabel;
|
||||
|
||||
// MQTT客户端 - 添加缺失的成员变量
|
||||
// MQTT客户端
|
||||
MqttClient *mqttClient;
|
||||
|
||||
// 灯条SN管理相关成员变量
|
||||
// 更新相关成员变量
|
||||
QString currentVersion;
|
||||
QString updateServerUrl;
|
||||
QNetworkAccessManager *updateNetworkManager;
|
||||
QNetworkReply *updateCheckReply;
|
||||
QNetworkReply *updateDownloadReply;
|
||||
QString downloadedUpdatePath;
|
||||
|
||||
// 数据管理
|
||||
QSet<QString> uniqueSnSet;
|
||||
QList<QCheckBox*> lightStripCheckBoxes; // 添加复选框列表
|
||||
QSettings *settings;
|
||||
|
||||
249
src/updatesettingsdialog.cpp
Normal file
249
src/updatesettingsdialog.cpp
Normal file
@ -0,0 +1,249 @@
|
||||
#include "updatesettingsdialog.h"
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
#include <QUrl>
|
||||
#include <QTimer>
|
||||
#include <QSpinBox>
|
||||
|
||||
UpdateSettingsDialog::UpdateSettingsDialog(QWidget *parent)
|
||||
: QDialog(parent),
|
||||
serverUrlEdit(nullptr),
|
||||
autoCheckBox(nullptr),
|
||||
checkIntervalEdit(nullptr),
|
||||
testBtn(nullptr),
|
||||
resetBtn(nullptr),
|
||||
okBtn(nullptr),
|
||||
cancelBtn(nullptr),
|
||||
settings(nullptr)
|
||||
{
|
||||
settings = new QSettings("TuxiApp", "LightStripSN", this);
|
||||
setupUI();
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
UpdateSettingsDialog::~UpdateSettingsDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateSettingsDialog::setupUI()
|
||||
{
|
||||
qDebug() << "开始设置UpdateSettingsDialog UI...";
|
||||
|
||||
setWindowTitle("更新设置");
|
||||
setFixedSize(400, 300);
|
||||
setModal(true);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
if (!mainLayout) {
|
||||
qDebug() << "错误: 无法创建主布局";
|
||||
return;
|
||||
}
|
||||
|
||||
// 服务器设置组
|
||||
QGroupBox *serverGroup = new QGroupBox("服务器设置", this);
|
||||
if (!serverGroup) {
|
||||
qDebug() << "错误: 无法创建服务器设置组";
|
||||
return;
|
||||
}
|
||||
|
||||
QFormLayout *serverLayout = new QFormLayout(serverGroup);
|
||||
if (!serverLayout) {
|
||||
qDebug() << "错误: 无法创建服务器布局";
|
||||
return;
|
||||
}
|
||||
|
||||
serverUrlEdit = new QLineEdit(this);
|
||||
if (!serverUrlEdit) {
|
||||
qDebug() << "错误: 无法创建服务器URL编辑框";
|
||||
return;
|
||||
}
|
||||
serverUrlEdit->setPlaceholderText("http://180.163.74.83:8001/version");
|
||||
serverLayout->addRow("更新服务器地址:", serverUrlEdit);
|
||||
|
||||
QHBoxLayout *testLayout = new QHBoxLayout();
|
||||
testBtn = new QPushButton("测试连接", this);
|
||||
resetBtn = new QPushButton("恢复默认", this);
|
||||
|
||||
if (!testBtn || !resetBtn) {
|
||||
qDebug() << "错误: 无法创建测试或重置按钮";
|
||||
return;
|
||||
}
|
||||
|
||||
testLayout->addWidget(testBtn);
|
||||
testLayout->addWidget(resetBtn);
|
||||
testLayout->addStretch();
|
||||
serverLayout->addRow("", testLayout);
|
||||
|
||||
mainLayout->addWidget(serverGroup);
|
||||
|
||||
// 自动检查设置组
|
||||
QGroupBox *autoGroup = new QGroupBox("自动检查设置", this);
|
||||
QFormLayout *autoLayout = new QFormLayout(autoGroup);
|
||||
|
||||
autoCheckBox = new QCheckBox("启用自动检查更新", this);
|
||||
autoLayout->addRow(autoCheckBox);
|
||||
|
||||
checkIntervalEdit = new QLineEdit(this);
|
||||
checkIntervalEdit->setPlaceholderText("24");
|
||||
QLabel *intervalLabel = new QLabel("检查间隔(小时):", this);
|
||||
autoLayout->addRow(intervalLabel, checkIntervalEdit);
|
||||
|
||||
// 当自动检查被禁用时,禁用间隔设置
|
||||
connect(autoCheckBox, &QCheckBox::toggled, [this, intervalLabel](bool checked) {
|
||||
checkIntervalEdit->setEnabled(checked);
|
||||
intervalLabel->setEnabled(checked);
|
||||
});
|
||||
|
||||
mainLayout->addWidget(autoGroup);
|
||||
|
||||
// 按钮布局
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout();
|
||||
buttonLayout->addStretch();
|
||||
|
||||
okBtn = new QPushButton("确定", this);
|
||||
cancelBtn = new QPushButton("取消", this);
|
||||
|
||||
buttonLayout->addWidget(okBtn);
|
||||
buttonLayout->addWidget(cancelBtn);
|
||||
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
// 连接信号槽
|
||||
connect(okBtn, &QPushButton::clicked, this, &UpdateSettingsDialog::onOkClicked);
|
||||
connect(cancelBtn, &QPushButton::clicked, this, &UpdateSettingsDialog::onCancelClicked);
|
||||
connect(testBtn, &QPushButton::clicked, this, &UpdateSettingsDialog::onTestConnectionClicked);
|
||||
connect(resetBtn, &QPushButton::clicked, this, &UpdateSettingsDialog::onResetToDefaultClicked);
|
||||
|
||||
qDebug() << "UpdateSettingsDialog UI设置完成";
|
||||
}
|
||||
|
||||
|
||||
void UpdateSettingsDialog::loadSettings()
|
||||
{
|
||||
QString defaultUrl = "http://180.163.74.83:8001/version";
|
||||
serverUrlEdit->setText(settings->value("updateServerUrl", defaultUrl).toString());
|
||||
autoCheckBox->setChecked(settings->value("autoCheckUpdates", true).toBool());
|
||||
checkIntervalEdit->setText(settings->value("checkInterval", 24).toString());
|
||||
|
||||
// 触发复选框状态变化以更新UI
|
||||
emit autoCheckBox->toggled(autoCheckBox->isChecked());
|
||||
}
|
||||
|
||||
void UpdateSettingsDialog::saveSettings()
|
||||
{
|
||||
settings->setValue("updateServerUrl", serverUrlEdit->text().trimmed());
|
||||
settings->setValue("autoCheckUpdates", autoCheckBox->isChecked());
|
||||
settings->setValue("checkInterval", checkIntervalEdit->text().toInt());
|
||||
settings->sync();
|
||||
}
|
||||
|
||||
QString UpdateSettingsDialog::getUpdateServerUrl() const
|
||||
{
|
||||
return serverUrlEdit->text().trimmed();
|
||||
}
|
||||
|
||||
bool UpdateSettingsDialog::isAutoCheckEnabled() const
|
||||
{
|
||||
return autoCheckBox->isChecked();
|
||||
}
|
||||
|
||||
int UpdateSettingsDialog::getCheckInterval() const
|
||||
{
|
||||
return checkIntervalEdit->text().toInt();
|
||||
}
|
||||
|
||||
void UpdateSettingsDialog::onOkClicked()
|
||||
{
|
||||
// 验证输入
|
||||
QString url = serverUrlEdit->text().trimmed();
|
||||
if (url.isEmpty()) {
|
||||
QMessageBox::warning(this, "输入错误", "请输入更新服务器地址!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
||||
QMessageBox::warning(this, "输入错误", "服务器地址必须以 http:// 或 https:// 开头!");
|
||||
return;
|
||||
}
|
||||
|
||||
int interval = checkIntervalEdit->text().toInt();
|
||||
if (autoCheckBox->isChecked() && (interval < 1 || interval > 168)) {
|
||||
QMessageBox::warning(this, "输入错误", "检查间隔必须在1-168小时之间!");
|
||||
return;
|
||||
}
|
||||
|
||||
saveSettings();
|
||||
accept();
|
||||
}
|
||||
|
||||
void UpdateSettingsDialog::onCancelClicked()
|
||||
{
|
||||
reject();
|
||||
}
|
||||
|
||||
void UpdateSettingsDialog::onTestConnectionClicked()
|
||||
{
|
||||
QString url = serverUrlEdit->text().trimmed();
|
||||
if (url.isEmpty()) {
|
||||
QMessageBox::warning(this, "测试失败", "请先输入服务器地址!");
|
||||
return;
|
||||
}
|
||||
|
||||
testConnection();
|
||||
}
|
||||
|
||||
void UpdateSettingsDialog::onResetToDefaultClicked()
|
||||
{
|
||||
int ret = QMessageBox::question(this, "确认重置",
|
||||
"确定要恢复默认设置吗?",
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (ret == QMessageBox::Yes) {
|
||||
serverUrlEdit->setText("http://180.163.74.83:8001/version");
|
||||
autoCheckBox->setChecked(true);
|
||||
checkIntervalEdit->setText("24");
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateSettingsDialog::testConnection()
|
||||
{
|
||||
testBtn->setEnabled(false);
|
||||
testBtn->setText("测试中...");
|
||||
|
||||
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
|
||||
QNetworkRequest request;
|
||||
request.setUrl(QUrl(serverUrlEdit->text().trimmed()));
|
||||
request.setRawHeader("User-Agent", "LightStripSN-Updater/1.0");
|
||||
|
||||
// 设置超时
|
||||
QTimer *timer = new QTimer(this);
|
||||
timer->setSingleShot(true);
|
||||
|
||||
QNetworkReply *reply = manager->get(request);
|
||||
|
||||
connect(timer, &QTimer::timeout, [this, reply]() {
|
||||
reply->abort();
|
||||
testBtn->setEnabled(true);
|
||||
testBtn->setText("测试连接");
|
||||
QMessageBox::warning(this, "连接超时", "连接服务器超时,请检查网络或服务器地址!");
|
||||
});
|
||||
|
||||
connect(reply, &QNetworkReply::finished, [this, reply, timer]() {
|
||||
timer->stop();
|
||||
testBtn->setEnabled(true);
|
||||
testBtn->setText("测试连接");
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
QMessageBox::information(this, "连接成功", "服务器连接正常!");
|
||||
} else {
|
||||
QMessageBox::warning(this, "连接失败",
|
||||
QString("连接失败: %1").arg(reply->errorString()));
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
timer->deleteLater();
|
||||
});
|
||||
|
||||
timer->start(10000); // 10秒超时
|
||||
}
|
||||
51
src/updatesettingsdialog.h
Normal file
51
src/updatesettingsdialog.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef UPDATESETTINGSDIALOG_H
|
||||
#define UPDATESETTINGSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QFormLayout>
|
||||
#include <QLabel>
|
||||
#include <QGroupBox>
|
||||
#include <QCheckBox>
|
||||
#include <QSettings>
|
||||
#include <QSpinBox>
|
||||
|
||||
class UpdateSettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit UpdateSettingsDialog(QWidget *parent = nullptr);
|
||||
~UpdateSettingsDialog();
|
||||
|
||||
QString getUpdateServerUrl() const;
|
||||
bool isAutoCheckEnabled() const;
|
||||
int getCheckInterval() const;
|
||||
|
||||
private slots:
|
||||
void onOkClicked();
|
||||
void onCancelClicked();
|
||||
void onTestConnectionClicked();
|
||||
void onResetToDefaultClicked();
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
void testConnection();
|
||||
|
||||
QLineEdit *serverUrlEdit;
|
||||
QCheckBox *autoCheckBox;
|
||||
QLineEdit *checkIntervalEdit;
|
||||
QPushButton *testBtn;
|
||||
QPushButton *resetBtn;
|
||||
QPushButton *okBtn;
|
||||
QPushButton *cancelBtn;
|
||||
|
||||
QSettings *settings;
|
||||
};
|
||||
|
||||
#endif // UPDATESETTINGSDIALOG_H
|
||||
Loading…
Reference in New Issue
Block a user