From f3bc18377633d50049ade0423aedc4f0eb815de6 Mon Sep 17 00:00:00 2001 From: zzh <838331105@qq.com> Date: Thu, 11 Sep 2025 14:40:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=86=E7=BB=84=E7=82=B9?= =?UTF-8?q?=E4=BA=AE=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E7=81=AF=E6=9D=A1=E6=97=B6=E7=9A=84=E5=BC=B9=E6=A1=86?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lightstripmanager.cpp | 203 +++++++++++++++++++++++++++++++------- src/lightstripmanager.h | 21 +++- src/mainwindow.cpp | 107 ++++++++++++++++++-- 3 files changed, 289 insertions(+), 42 deletions(-) diff --git a/src/lightstripmanager.cpp b/src/lightstripmanager.cpp index d71997c..a43bf26 100644 --- a/src/lightstripmanager.cpp +++ b/src/lightstripmanager.cpp @@ -16,7 +16,7 @@ LightStripManager::LightStripManager(QWidget *parent) setWindowIcon(QIcon(":/icons/lightstrip.png")); // 设置初始窗口大小和位置 - resize(1000, 800); + resize(1000, 900); // 居中显示到父窗口 if (parent) { @@ -39,7 +39,7 @@ LightStripManager::LightStripManager(QWidget *parent) } // 设置最小尺寸 - setMinimumSize(700, 600); + setMinimumSize(700, 700); // 彻底修复背景透明问题 setStyleSheet( @@ -468,6 +468,24 @@ 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); mainSplitter->addWidget(lightControlGroup); @@ -1121,88 +1139,205 @@ void LightStripManager::setMainWindow(MainWindow *mainWindow) { m_mainWindow = mainWindow; } + +void LightStripManager::onGroupLightClicked() +{ + // 检查身份信息配置 + if (label1Edit->text().isEmpty() || label2Edit->text().isEmpty() || label3Edit->text().isEmpty()) { + QMessageBox::warning(this, "警告", "请先配置完整的身份信息(label1、label2、label3)!"); + return; + } + + // 获取点亮参数 + QString color = colorCombo->currentText().split("-")[0]; + int flash = flashCombo->currentText().split("-")[0].toInt(); + int duration = lightDurationSpin->value(); + bool sound = soundCombo->currentIndex() == 1; // 正确获取sound值 + int flashInterval = flashIntervalSpin->value(); // 正确获取flashInterval值 + + // 获取各label的匹配规则(转换为int) + int rule1 = rule1ComboBox->currentText().split("-")[0].toInt(); + int rule2 = rule2ComboBox->currentText().split("-")[0].toInt(); + int rule3 = rule3ComboBox->currentText().split("-")[0].toInt(); + + // 发射分组点亮信号(添加sound和flashInterval参数) + emit groupLightRequested(label1Edit->text(), label2Edit->text(), label3Edit->text(), + rule1, rule2, rule3, color, flash, duration, sound, flashInterval); + + // 显示操作结果 + bindingStatusLabel->setText("分组点亮指令已发送"); + bindingStatusLabel->setStyleSheet("QLabel { color: green; }"); +} void LightStripManager::setupIdentityBindingArea() { identityBindingGroup = new QGroupBox("身份信息绑定", this); identityBindingGroup->setStyleSheet( "QGroupBox { " - " color: #000000; " " font-weight: bold; " " font-size: 14px; " - " padding-top: 15px; " - " border: 2px solid #ddd; " + " border: 2px solid #cccccc; " " border-radius: 8px; " " margin-top: 10px; " + " padding-top: 10px; " + "} " + "QGroupBox::title { " + " subcontrol-origin: margin; " + " left: 10px; " + " padding: 0 5px 0 5px; " "}" ); - identityBindingGroup->setMaximumHeight(150); QVBoxLayout *identityLayout = new QVBoxLayout(identityBindingGroup); - // 第一行:身份信息参数 - QHBoxLayout *row1Layout = new QHBoxLayout(); - + // Label1行:输入框 + 匹配规则 + QHBoxLayout *label1Layout = new QHBoxLayout(); QLabel *label1Label = new QLabel("Label1:"); - label1Label->setStyleSheet("QLabel { color: #000000; }"); - row1Layout->addWidget(label1Label); + label1Label->setMinimumWidth(60); + label1Label->setStyleSheet( + "QLabel { " + " font-weight: bold; " + " font-size: 12px; " + " color: #333; " + " padding: 5px; " + "}" + ); + label1Layout->addWidget(label1Label); label1Edit = new QLineEdit(); - label1Edit->setPlaceholderText("输入Label1参数..."); - label1Edit->setMinimumHeight(30); + label1Edit->setPlaceholderText("请输入Label1值"); + label1Edit->setMinimumHeight(35); label1Edit->setStyleSheet( "QLineEdit { " - " color: #000000; " + " padding: 8px; " " border: 2px solid #ddd; " - " border-radius: 6px; " - " padding: 5px 10px; " + " border-radius: 4px; " " font-size: 12px; " "} " "QLineEdit:focus { border-color: #2196F3; }" ); connect(label1Edit, &QLineEdit::textChanged, this, &LightStripManager::onLabel1Changed); - row1Layout->addWidget(label1Edit); + label1Layout->addWidget(label1Edit); + rule1ComboBox = new QComboBox(); + rule1ComboBox->addItem("= (等于)", 1); + rule1ComboBox->addItem("> (大于)", 2); + rule1ComboBox->addItem("< (小于)", 3); + rule1ComboBox->addItem("≠ (不等于)", 4); + rule1ComboBox->addItem("∅ (不参与匹配)", 0); + rule1ComboBox->setMinimumWidth(120); + rule1ComboBox->setStyleSheet( + "QComboBox { " + " padding: 8px; " + " border: 2px solid #ddd; " + " border-radius: 4px; " + " font-size: 12px; " + " background-color: white; " + "} " + "QComboBox:focus { border-color: #2196F3; }" + ); + label1Layout->addWidget(rule1ComboBox); + + identityLayout->addLayout(label1Layout); + + // Label2行:输入框 + 匹配规则 + QHBoxLayout *label2Layout = new QHBoxLayout(); QLabel *label2Label = new QLabel("Label2:"); - label2Label->setStyleSheet("QLabel { color: #000000; }"); - row1Layout->addWidget(label2Label); + label2Label->setMinimumWidth(60); + label2Label->setStyleSheet( + "QLabel { " + " font-weight: bold; " + " font-size: 12px; " + " color: #333; " + " padding: 5px; " + "}" + ); + label2Layout->addWidget(label2Label); label2Edit = new QLineEdit(); - label2Edit->setPlaceholderText("输入Label2参数..."); - label2Edit->setMinimumHeight(30); + label2Edit->setPlaceholderText("请输入Label2值"); + label2Edit->setMinimumHeight(35); label2Edit->setStyleSheet( "QLineEdit { " - " color: #000000; " + " padding: 8px; " " border: 2px solid #ddd; " - " border-radius: 6px; " - " padding: 5px 10px; " + " border-radius: 4px; " " font-size: 12px; " "} " "QLineEdit:focus { border-color: #2196F3; }" ); connect(label2Edit, &QLineEdit::textChanged, this, &LightStripManager::onLabel2Changed); - row1Layout->addWidget(label2Edit); + label2Layout->addWidget(label2Edit); + rule2ComboBox = new QComboBox(); + rule2ComboBox->addItem("= (等于)", 1); + rule2ComboBox->addItem("> (大于)", 2); + rule2ComboBox->addItem("< (小于)", 3); + rule2ComboBox->addItem("≠ (不等于)", 4); + rule2ComboBox->addItem("∅ (不参与匹配)", 0); + rule2ComboBox->setMinimumWidth(120); + rule2ComboBox->setStyleSheet( + "QComboBox { " + " padding: 8px; " + " border: 2px solid #ddd; " + " border-radius: 4px; " + " font-size: 12px; " + " background-color: white; " + "} " + "QComboBox:focus { border-color: #2196F3; }" + ); + label2Layout->addWidget(rule2ComboBox); + + identityLayout->addLayout(label2Layout); + + // Label3行:输入框 + 匹配规则 + QHBoxLayout *label3Layout = new QHBoxLayout(); QLabel *label3Label = new QLabel("Label3:"); - label3Label->setStyleSheet("QLabel { color: #000000; }"); - row1Layout->addWidget(label3Label); + label3Label->setMinimumWidth(60); + label3Label->setStyleSheet( + "QLabel { " + " font-weight: bold; " + " font-size: 12px; " + " color: #333; " + " padding: 5px; " + "}" + ); + label3Layout->addWidget(label3Label); label3Edit = new QLineEdit(); - label3Edit->setPlaceholderText("输入Label3参数..."); - label3Edit->setMinimumHeight(30); + label3Edit->setPlaceholderText("请输入Label3值"); + label3Edit->setMinimumHeight(35); label3Edit->setStyleSheet( "QLineEdit { " - " color: #000000; " + " padding: 8px; " " border: 2px solid #ddd; " - " border-radius: 6px; " - " padding: 5px 10px; " + " border-radius: 4px; " " font-size: 12px; " "} " "QLineEdit:focus { border-color: #2196F3; }" ); connect(label3Edit, &QLineEdit::textChanged, this, &LightStripManager::onLabel3Changed); - row1Layout->addWidget(label3Edit); + label3Layout->addWidget(label3Edit); - identityLayout->addLayout(row1Layout); + rule3ComboBox = new QComboBox(); + rule3ComboBox->addItem("= (等于)", 1); + rule3ComboBox->addItem("> (大于)", 2); + rule3ComboBox->addItem("< (小于)", 3); + rule3ComboBox->addItem("≠ (不等于)", 4); + rule3ComboBox->addItem("∅ (不参与匹配)", 0); + rule3ComboBox->setMinimumWidth(120); + rule3ComboBox->setStyleSheet( + "QComboBox { " + " padding: 8px; " + " border: 2px solid #ddd; " + " border-radius: 4px; " + " font-size: 12px; " + " background-color: white; " + "} " + "QComboBox:focus { border-color: #2196F3; }" + ); + label3Layout->addWidget(rule3ComboBox); + + identityLayout->addLayout(label3Layout); // 第二行:绑定按钮和状态显示 QHBoxLayout *row2Layout = new QHBoxLayout(); diff --git a/src/lightstripmanager.h b/src/lightstripmanager.h index ce5d43a..308bf34 100644 --- a/src/lightstripmanager.h +++ b/src/lightstripmanager.h @@ -54,6 +54,10 @@ signals: void snCountChanged(int count); // 新增:身份信息绑定信号 void identityBindingRequested(const QString &sn, const QString &label1, const QString &label2, const QString &label3); + // 修改:分组点亮信号(添加sound和flashInterval参数) + void groupLightRequested(const QString &label1, const QString &label2, const QString &label3, + int rule1, int rule2, int rule3, + const QString &color, int blink, int duration, bool sound, int flashInterval); private slots: void onClearSnListClicked(); @@ -73,6 +77,8 @@ private slots: void onLabel1Changed(const QString &text); void onLabel2Changed(const QString &text); void onLabel3Changed(const QString &text); + // 新增:分组点亮槽函数 + void onGroupLightClicked(); private: void setupUI(); @@ -135,12 +141,17 @@ private: QComboBox *soundCombo; QPushButton *sendLightSelectedBtn; QPushButton *sendLightAllBtn; + // 新增:分组点亮按钮 + QPushButton *groupLightBtn; // 新增:身份信息绑定区域 QGroupBox *identityBindingGroup; QLineEdit *label1Edit; - QLineEdit *label2Edit; + QLineEdit *label2Edit; QLineEdit *label3Edit; + QComboBox *rule1ComboBox; // label1的匹配规则 + QComboBox *rule2ComboBox; // label2的匹配规则 + QComboBox *rule3ComboBox; // label3的匹配规则 QPushButton *bindIdentitySelectedBtn; QPushButton *bindIdentityAllBtn; QLabel *bindingStatusLabel; @@ -163,6 +174,14 @@ private: QString currentLabel1; QString currentLabel2; QString currentLabel3; + public: + enum MatchRule { + EQUAL = 0, // = (00) + GREATER = 1, // > (01) + LESS = 2, // < (02) + NOT_EQUAL = 3, // ≠ (03) + NO_MATCH = 4 // ∅ (04) 不参与匹配 + }; }; #endif // LIGHTSTRIPMANAGER_H \ No newline at end of file diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3e9fdad..15dd10d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -815,13 +815,23 @@ void MainWindow::sendSearchLightStripCommand() { QString jsonString = doc.toJson(QJsonDocument::Compact); // 发送消息 - mqttClient->publish(topic, jsonString); - - messageDisplay->append(QString("[%1] 发送搜索灯条命令") - .arg(QDateTime::currentDateTime().toString("hh:mm:ss"))); - messageDisplay->append(QString("Topic: %1").arg(topic)); - messageDisplay->append(QString("Message: %1").arg(jsonString)); - messageDisplay->append("---"); + if (mqttClient->publish(topic, jsonString)) { + messageDisplay->append(QString("[%1] 发送搜索灯条命令") + .arg(QDateTime::currentDateTime().toString("hh:mm:ss"))); + messageDisplay->append(QString("Topic: %1").arg(topic)); + messageDisplay->append(QString("Message: %1").arg(jsonString)); + messageDisplay->append("---"); + + // 弹出提示框 + QMessageBox::information(this, "搜索灯条", "正在搜索灯条,请等待2分钟返回结果..."); + } else { + messageDisplay->append(QString("[%1] 发送搜索灯条命令失败") + .arg(QDateTime::currentDateTime().toString("hh:mm:ss"))); + messageDisplay->append("---"); + + // 弹出错误提示框 + QMessageBox::warning(this, "错误", "发送搜索灯条命令失败,请检查网络连接"); + } } void MainWindow::sendOtaCommand(const QString& version, bool isUpgrade) { @@ -1191,6 +1201,89 @@ void MainWindow::openLightStripManager() } }); + // 新增:连接分组点亮信号 + connect(lightStripManager, &LightStripManager::groupLightRequested, + this, [this](const QString &label1, const QString &label2, const QString &label3, + int rule1, int rule2, int rule3, const QString &color, int flash, int duration, bool sound, int flashInterval) { + + // 检查MQTT连接状态 + if (!mqttClient->isConnected()) { + qDebug() << "MQTT未连接,无法发送分组点亮命令"; + QMessageBox::warning(this, "警告", "MQTT未连接,请先连接MQTT服务器"); + return; + } + + // 获取设备SN + QString deviceSn = deviceSnEdit->text().trimmed(); + if (deviceSn.isEmpty()) { + QMessageBox::warning(this, "警告", "请先输入需要测试的设备SN"); + return; + } + + // 构建labelConfig对象 + QJsonObject labelConfig; + labelConfig["label1"] = label1; + labelConfig["label2"] = label2; + labelConfig["label3"] = label3; + labelConfig["label1Rule"] = QString("%1").arg(rule1, 2, 10, QChar('0')); + labelConfig["label2Rule"] = QString("%1").arg(rule2, 2, 10, QChar('0')); + labelConfig["label3Rule"] = QString("%1").arg(rule3, 2, 10, QChar('0')); + + // 构建分组点亮消息数据 + QJsonObject msgData; + msgData["labelConfig"] = labelConfig; + msgData["color"] = color; + msgData["sound"] = sound ? "1" : "0"; + msgData["flash"] = QString::number(flash); + msgData["flashInterval"] = QString::number(flashInterval); + msgData["lightDuration"] = QString::number(duration); + + // 构建完整的msg对象 + QJsonObject fullMsg; + fullMsg["msgType"] = "3023"; + fullMsg["data"] = msgData; + + // 转换msg为JSON字符串 + QJsonDocument msgDoc(fullMsg); + QString msgString = msgDoc.toJson(QJsonDocument::Compact); + + // 构建最外层消息 + QJsonObject outerMessage; + outerMessage["deviceId"] = ""; + outerMessage["messageId"] = QString::number(QDateTime::currentMSecsSinceEpoch()); + outerMessage["msg"] = msgString; + outerMessage["timestamp"] = QDateTime::currentMSecsSinceEpoch(); + + // 转换为最终JSON字符串 + QJsonDocument finalDoc(outerMessage); + QString finalMessage = finalDoc.toJson(QJsonDocument::Compact); + + // 构建MQTT主题 + QString topic = QString("iot/10045/%1/message/adviceDevice").arg(deviceSn); + + // 发送MQTT消息 + bool success = mqttClient->publish(topic, finalMessage); + + if (success) { + qDebug() << "成功发送分组点亮命令"; + qDebug() << "主题:" << topic; + qDebug() << "消息:" << finalMessage; + + // 在消息显示区域显示发送的消息 + messageDisplay->append(QString("[%1] 发送分组点亮命令到设备 %2") + .arg(QDateTime::currentDateTime().toString("hh:mm:ss")) + .arg(deviceSn)); + messageDisplay->append(QString("主题: %1").arg(topic)); + messageDisplay->append(QString("匹配规则: Label1=%1(rule:%2), Label2=%3(rule:%4), Label3=%5(rule:%6)") + .arg(label1).arg(rule1, 2, 10, QChar('0')) + .arg(label2).arg(rule2, 2, 10, QChar('0')) + .arg(label3).arg(rule3, 2, 10, QChar('0'))); + } else { + qDebug() << "发送分组点亮命令失败"; + QMessageBox::warning(this, "错误", "发送MQTT消息失败,请检查网络连接"); + } + }); + // 连接关闭信号 connect(lightStripManager, &QWidget::destroyed, this, &MainWindow::onLightStripManagerClosed);