添加触发配置,逻辑配置

This commit is contained in:
zhangsheng 2025-04-19 16:25:33 +08:00
parent 8f75f5672c
commit 37cd43791e
18 changed files with 1104 additions and 352 deletions

View File

@ -24,9 +24,12 @@ SOURCES += \
relaysetting.cpp \ relaysetting.cpp \
seismic_monitor.cpp \ seismic_monitor.cpp \
setpoint.cpp \ setpoint.cpp \
setpoint_tachometer.cpp \
singlerelay.cpp \ singlerelay.cpp \
singlerelay_data.cpp \
tachometer.cpp \ tachometer.cpp \
tachometer_data.cpp \ tachometer_data.cpp \
tmrrelayassociation.cpp \
velocity.cpp \ velocity.cpp \
vibrationdata.cpp vibrationdata.cpp
@ -48,9 +51,12 @@ HEADERS += \
relaysetting.h \ relaysetting.h \
seismic_monitor.h \ seismic_monitor.h \
setpoint.h \ setpoint.h \
setpoint_tachometer.h \
singlerelay.h \ singlerelay.h \
singlerelay_data.h \
tachometer.h \ tachometer.h \
tachometer_data.h \ tachometer_data.h \
tmrrelayassociation.h \
velocity.h \ velocity.h \
velocity_ds.h \ velocity_ds.h \
vibrationdata.h vibrationdata.h
@ -64,6 +70,7 @@ FORMS += \
relaysetting.ui \ relaysetting.ui \
seismic_monitor.ui \ seismic_monitor.ui \
setpoint.ui \ setpoint.ui \
setpoint_tachometer.ui \
singlerelay.ui \ singlerelay.ui \
tachometer.ui \ tachometer.ui \
tmrrelayassociation.ui \ tmrrelayassociation.ui \

View File

@ -8,6 +8,7 @@
#include "vibrationdata.h" #include "vibrationdata.h"
#include "tachometer_data.h" #include "tachometer_data.h"
#include "keyphase_data.h" #include "keyphase_data.h"
#include "singlerelay_data.h"
#include <QCoreApplication> #include <QCoreApplication>
@ -35,13 +36,15 @@ void ConfigMgr::Save(QString & file_path) {
card_type_[i] != kCardSpeedTMRPrimary && card_type_[i] != kCardSpeedTMRPrimary &&
card_type_[i] != kCardKeyphaseSingle && card_type_[i] != kCardKeyphaseSingle &&
card_type_[i] != kCardRelaySingle && card_type_[i] != kCardRelaySingle &&
card_type_[i] != kCardRelayTMRPrimary) { card_type_[i] != kCardRelayTMRPrimary &&
card_type_[i] != kCardRelaySingleNOK) {
continue; continue;
} }
// process slot // process slot
QJsonObject slot_item; QJsonObject slot_item;
if (card_type_[i] != kCardRelaySingle && if (card_type_[i] != kCardRelaySingle &&
card_type_[i] != kCardRelayTMRPrimary) { card_type_[i] != kCardRelayTMRPrimary &&
card_type_[i] != kCardRelaySingleNOK) {
for (int cid = 0; cid < CHANNEL_COUNT; ++cid) { for (int cid = 0; cid < CHANNEL_COUNT; ++cid) {
QJsonObject channel_item; QJsonObject channel_item;
if (card_type_[i] == kCardVibSingle || if (card_type_[i] == kCardVibSingle ||
@ -64,17 +67,17 @@ void ConfigMgr::Save(QString & file_path) {
voltage_range.append(ptr->base_config_[cid].normal_voltage_high); voltage_range.append(ptr->base_config_[cid].normal_voltage_high);
channel_item["normal_voltage_range"] = voltage_range; channel_item["normal_voltage_range"] = voltage_range;
QJsonObject setpoint_data; QJsonObject setpoint_data;
setpoint_data["direct_upper"] = qRound(ptr->vib_alert_danger[cid].direct_upper * 10)/10.0; setpoint_data["direct_upper"] = qRound(ptr->alert_danger[cid].direct_upper * 10)/10.0;
setpoint_data["direct_enable"] = ptr->vib_alert_danger[cid].direct_enable; setpoint_data["direct_enable"] = ptr->alert_danger[cid].direct_enable;
setpoint_data["1x_ampl_upper"] = qRound(ptr->vib_alert_danger[cid].x1_ampl_upper * 10)/10.0; setpoint_data["1x_ampl_upper"] = qRound(ptr->alert_danger[cid].x1_ampl_upper * 10)/10.0;
setpoint_data["1x_ampl_lower"] = qRound(ptr->vib_alert_danger[cid].x1_ampl_lower * 10)/10.0; setpoint_data["1x_ampl_lower"] = qRound(ptr->alert_danger[cid].x1_ampl_lower * 10)/10.0;
setpoint_data["1x_ampl_enable"] = ptr->vib_alert_danger[cid].x1_ampl_enable; setpoint_data["1x_ampl_enable"] = ptr->alert_danger[cid].x1_ampl_enable;
setpoint_data["2x_ampl_upper"] = qRound(ptr->vib_alert_danger[cid].x2_ampl_upper * 10)/10.0; setpoint_data["2x_ampl_upper"] = qRound(ptr->alert_danger[cid].x2_ampl_upper * 10)/10.0;
setpoint_data["2x_ampl_lower"] = qRound(ptr->vib_alert_danger[cid].x2_ampl_lower * 10)/10.0; setpoint_data["2x_ampl_lower"] = qRound(ptr->alert_danger[cid].x2_ampl_lower * 10)/10.0;
setpoint_data["2x_ampl_enable"] = ptr->vib_alert_danger[cid].x2_ampl_enable; setpoint_data["2x_ampl_enable"] = ptr->alert_danger[cid].x2_ampl_enable;
setpoint_data["danger_param"] = ptr->vib_alert_danger[cid].danger_param; setpoint_data["danger_param"] = ptr->alert_danger[cid].danger_param;
setpoint_data["danger_upper"] = qRound(ptr->vib_alert_danger[cid].danger_upper * 10)/10.0; setpoint_data["danger_upper"] = qRound(ptr->alert_danger[cid].danger_upper * 10)/10.0;
setpoint_data["danger_enable"] = ptr->vib_alert_danger[cid].danger_enable; setpoint_data["danger_enable"] = ptr->alert_danger[cid].danger_enable;
channel_item["setpoint"] = setpoint_data; channel_item["setpoint"] = setpoint_data;
// variables // variables
QJsonObject variables; QJsonObject variables;
@ -226,6 +229,16 @@ void ConfigMgr::Save(QString & file_path) {
QJsonArray voltage_range_array; QJsonArray voltage_range_array;
voltage_range_array.append(ptr->variables_[cid].normal_voltage_low); voltage_range_array.append(ptr->variables_[cid].normal_voltage_low);
voltage_range_array.append(ptr->variables_[cid].normal_voltage_high); voltage_range_array.append(ptr->variables_[cid].normal_voltage_high);
QJsonObject setpoint_data;
setpoint_data["speed_upper"] = qRound(ptr->alert_danger[cid].speed_upper * 10)/10.0;
setpoint_data["speed_lower"] = ptr->alert_danger[cid].speed_lower;
setpoint_data["speed_upper_enable"] = ptr->alert_danger[cid].speed_upper_enable;
setpoint_data["speed_lower_enable"] = ptr->alert_danger[cid].speed_lower_enable;
setpoint_data["danger_speed_upper"] = ptr->alert_danger[cid].danger_speed_upper;
setpoint_data["danger_speed_lower"] = ptr->alert_danger[cid].danger_speed_lower;
setpoint_data["danger_upper_enable"] = ptr->alert_danger[cid].danger_upper_enable;
setpoint_data["danger_lower_enable"] = ptr->alert_danger[cid].danger_lower_enable;
channel_item["setpoint"] = setpoint_data;
channel_item.insert("active", ptr->variables_[cid].active); channel_item.insert("active", ptr->variables_[cid].active);
channel_item.insert("normal_voltage_range", voltage_range_array); channel_item.insert("normal_voltage_range", voltage_range_array);
channel_item.insert("threshold", ptr->variables_[cid].threshold); channel_item.insert("threshold", ptr->variables_[cid].threshold);
@ -259,7 +272,24 @@ void ConfigMgr::Save(QString & file_path) {
} }
slot_item["version"] = 1; slot_item["version"] = 1;
}else{ }else{
// TODO: save relay data QJsonObject channel_item;
for(int ch = 0;ch < RELAY_COUNT;++ch){
if(card_type_[i] == kCardRelaySingleNOK){
std::shared_ptr<CardBase> base_ptr = ConfigMgr::Instance()->GetSlotPtr(slot);
if (base_ptr == nullptr) {
continue;
}
std::shared_ptr<SingleRelayDataNOK> ptr = std::dynamic_pointer_cast<SingleRelayDataNOK>(base_ptr);
channel_item.insert("logic_expression", ptr->single_relay_nok[ch].logic_expression);
}else if(card_type_[i] == kCardRelaySingle){
}else if(card_type_[i] == kCardRelayTMRPrimary){
}
slot_item[QString::number(ch + 1)] = channel_item;
}
slot_item["version"] = 1;
} }
doc_obj[QString::number(slot)] = slot_item; doc_obj[QString::number(slot)] = slot_item;
} }
@ -341,17 +371,17 @@ void ConfigMgr::Load(QString filename) {
vib_data->base_config_[j].power = channel["power"].toBool(); vib_data->base_config_[j].power = channel["power"].toBool();
//setpoint //setpoint
QJsonObject setpoint_data = channel["setpoint"].toObject(); QJsonObject setpoint_data = channel["setpoint"].toObject();
vib_data->vib_alert_danger[j].direct_upper = setpoint_data["direct_upper"].toDouble(); vib_data->alert_danger[j].direct_upper = setpoint_data["direct_upper"].toDouble();
vib_data->vib_alert_danger[j].direct_enable = setpoint_data["direct_enable"].toBool(); vib_data->alert_danger[j].direct_enable = setpoint_data["direct_enable"].toBool();
vib_data->vib_alert_danger[j].x1_ampl_upper = setpoint_data["1x_ampl_upper"].toDouble(); vib_data->alert_danger[j].x1_ampl_upper = setpoint_data["1x_ampl_upper"].toDouble();
vib_data->vib_alert_danger[j].x1_ampl_lower = setpoint_data["1x_ampl_lower"].toDouble(); vib_data->alert_danger[j].x1_ampl_lower = setpoint_data["1x_ampl_lower"].toDouble();
vib_data->vib_alert_danger[j].x1_ampl_enable = setpoint_data["1x_ampl_enable"].toBool(); vib_data->alert_danger[j].x1_ampl_enable = setpoint_data["1x_ampl_enable"].toBool();
vib_data->vib_alert_danger[j].x2_ampl_upper = setpoint_data["2x_ampl_upper"].toDouble(); vib_data->alert_danger[j].x2_ampl_upper = setpoint_data["2x_ampl_upper"].toDouble();
vib_data->vib_alert_danger[j].x2_ampl_lower = setpoint_data["2x_ampl_lower"].toDouble(); vib_data->alert_danger[j].x2_ampl_lower = setpoint_data["2x_ampl_lower"].toDouble();
vib_data->vib_alert_danger[j].x2_ampl_enable = setpoint_data["2x_ampl_enable"].toBool(); vib_data->alert_danger[j].x2_ampl_enable = setpoint_data["2x_ampl_enable"].toBool();
vib_data->vib_alert_danger[j].danger_param = setpoint_data["danger_param"].toInt(); vib_data->alert_danger[j].danger_param = setpoint_data["danger_param"].toInt();
vib_data->vib_alert_danger[j].danger_upper = setpoint_data["danger_upper"].toDouble(); vib_data->alert_danger[j].danger_upper = setpoint_data["danger_upper"].toDouble();
vib_data->vib_alert_danger[j].danger_enable = setpoint_data["danger_enable"].toBool(); vib_data->alert_danger[j].danger_enable = setpoint_data["danger_enable"].toBool();
// variables // variables
QJsonObject tmp_variable = channel["variable"].toObject(); QJsonObject tmp_variable = channel["variable"].toObject();
switch (vib_data->base_config_[j].channel_type) { switch (vib_data->base_config_[j].channel_type) {
@ -414,7 +444,7 @@ void ConfigMgr::Load(QString filename) {
// filter // filter
QJsonArray filter_array = tmp_variable["filter"].toArray(); QJsonArray filter_array = tmp_variable["filter"].toArray();
for (int k = 0; k < filter_array.size(); k++) { for (int k = 0; k < filter_array.size(); k++) {
QJsonObject filter_ele = filter_array[i].toObject(); QJsonObject filter_ele = filter_array[k].toObject();
variable->filter_[k].low = filter_ele["low"].toInt(); variable->filter_[k].low = filter_ele["low"].toInt();
variable->filter_[k].high = filter_ele["high"].toInt(); variable->filter_[k].high = filter_ele["high"].toInt();
variable->filter_[k].checked = filter_ele["checked"].toBool(); variable->filter_[k].checked = filter_ele["checked"].toBool();
@ -481,6 +511,17 @@ void ConfigMgr::Load(QString filename) {
speed_data->variables_[j].normal_latching = channel["normal_latching"].toBool(); speed_data->variables_[j].normal_latching = channel["normal_latching"].toBool();
speed_data->variables_[j].speed_peek = channel["speed_peak"].toInt(); speed_data->variables_[j].speed_peek = channel["speed_peak"].toInt();
speed_data->variables_[j].default_speed = channel["default_speed"].toInt(); speed_data->variables_[j].default_speed = channel["default_speed"].toInt();
QJsonObject setpoint_data = channel["setpoint"].toObject();
speed_data->alert_danger[j].speed_upper = setpoint_data["speed_upper"].toDouble();
speed_data->alert_danger[j].speed_lower = setpoint_data["speed_lower"].toDouble();
speed_data->alert_danger[j].speed_upper_enable = setpoint_data["speed_upper_enable"].toBool();
speed_data->alert_danger[j].speed_lower_enable = setpoint_data["speed_lower_enable"].toBool();
speed_data->alert_danger[j].danger_speed_upper = setpoint_data["danger_speed_upper"].toDouble();
speed_data->alert_danger[j].danger_speed_lower = setpoint_data["danger_speed_lower"].toDouble();
speed_data->alert_danger[j].danger_upper_enable = setpoint_data["danger_upper_enable"].toBool();
speed_data->alert_danger[j].danger_lower_enable = setpoint_data["danger_lower_enable"].toBool();
} }
cards_.push_back(speed_data); cards_.push_back(speed_data);
} else if (card_type_[i] == kCardKeyphaseSingle) { } else if (card_type_[i] == kCardKeyphaseSingle) {
@ -499,6 +540,16 @@ void ConfigMgr::Load(QString filename) {
keyphase_data->variables_[j].events_per_revolution = channel["events_per_revolution"].toInt(); keyphase_data->variables_[j].events_per_revolution = channel["events_per_revolution"].toInt();
} }
cards_.push_back(keyphase_data); cards_.push_back(keyphase_data);
}else if (card_type_[i] == kCardRelaySingleNOK || card_type_[i] == kCardRelayTMRPrimary || card_type_[i] == kCardRelaySingle){
std::shared_ptr<SingleRelayDataNOK> singlereay_data = std::make_shared<SingleRelayDataNOK>();
singlereay_data->slot_ = slot;
singlereay_data->card_type_ = static_cast<CardType>(card_type_[i]);
singlereay_data->version_ = temp_obj["version"].toInt();
for (int j = 0; j < RELAY_COUNT; ++j) {
channel = temp_obj[QString::number(j + 1)].toObject();
singlereay_data->single_relay_nok[j].logic_expression = channel["logic_expression"].toString();
}
cards_.push_back(singlereay_data);
} }
} }
} }

View File

@ -3,7 +3,33 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "cardbase.h" #include "cardbase.h"
#include <QDrag>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDebug>
#include <QListWidget>
class DraggableListWidget : public QListWidget {
public:
DraggableListWidget(QWidget *parent = nullptr) : QListWidget(parent) {
setDragEnabled(true);
}
protected:
void startDrag(Qt::DropActions supportedActions) override {
QListWidgetItem *item = currentItem();
if (!item) return;
QMimeData *mimeData = new QMimeData;
QString customData = item->data(Qt::UserRole).toString();
mimeData->setData("application/x-custom", customData.toUtf8());
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->exec(Qt::CopyAction);
}
};
class ConfigMgr { class ConfigMgr {
private: private:
static ConfigMgr *instance; static ConfigMgr *instance;

View File

@ -12,6 +12,7 @@ extern QString g_strServerIp; // 服务端IP
#define SLOT_NUM 15 #define SLOT_NUM 15
#define CHANNEL_COUNT 4 #define CHANNEL_COUNT 4
#define RELAY_COUNT 8
typedef enum { typedef enum {
kCardNone = 0, kCardNone = 0,
@ -32,6 +33,7 @@ typedef enum {
kCardRelaySingle = 32, kCardRelaySingle = 32,
kCardRelayTMRPrimary = 33, kCardRelayTMRPrimary = 33,
kCardRelayTMRBackup = 34, kCardRelayTMRBackup = 34,
kCardRelaySingleNOK = 35,
} CardType; } CardType;
@ -235,27 +237,43 @@ typedef struct VibAlertDanger_{
float danger_upper; float danger_upper;
bool danger_enable; bool danger_enable;
VibAlertDanger_(){ VibAlertDanger_(){
direct_upper = 0.0;
direct_enable = false; direct_enable = false;
x1_ampl_upper = 0.0;
x1_ampl_lower = 0.0;
x1_ampl_enable = false; x1_ampl_enable = false;
x2_ampl_upper = 0.0;
x2_ampl_lower = 0.0;
x2_ampl_enable = false; x2_ampl_enable = false;
danger_upper = 0.0;
danger_enable = false; danger_enable = false;
} }
} VibAlertDanger; } VibAlertDanger;
typedef struct{ typedef struct SpeedAlert_{
float speed_upper; float speed_upper;
float speed_lower; float speed_lower;
bool speed_upper_enable; bool speed_upper_enable;
bool speed_lower_enable; bool speed_lower_enable;
float speed_bnd_upper;
float speed_bnd_lower;
bool speed_bnd_enable;
float danger_speed_upper; float danger_speed_upper;
float danger_speed_lower; float danger_speed_lower;
bool danger_speed_upper_enable; bool danger_upper_enable;
bool danger_speed_lower_enable; bool danger_lower_enable;
SpeedAlert_(){
speed_upper = 0;
speed_lower = 0;
danger_speed_upper = 0;
danger_speed_lower = 0;
}
} SpeedAlert; } SpeedAlert;
typedef struct SingleRelayNOK_{
QString logic_expression;
SingleRelayNOK_(){
logic_expression = "";
}
} SingleRelayNOK;
#pragma pack(1) #pragma pack(1)
typedef struct { typedef struct {
uint8_t head[3]; // 固定值0xAA55AA uint8_t head[3]; // 固定值0xAA55AA

View File

@ -21,6 +21,8 @@
#include "config_mgr.h" #include "config_mgr.h"
#include "vibrationdata.h" #include "vibrationdata.h"
#include "connect.h" #include "connect.h"
#include "tmrrelayassociation.h"
#include "setpoint_tachometer.h"
QString g_strServerIp; QString g_strServerIp;
@ -215,8 +217,10 @@ void MainWindow::createMenu(const QString &rootTitle, QPushButton *parent) {
// 创建第二层子菜单:/DOM810 继电器模块 // 创建第二层子菜单:/DOM810 继电器模块
QAction *relays_1 = relays->addAction("/DOM810 单板卡"); QAction *relays_1 = relays->addAction("/DOM810 单板卡");
relays_1->setData(kCardRelaySingle); relays_1->setData(kCardRelaySingle);
QAction *relays_2 = relays->addAction("/DOM810 三冗余板卡"); QAction *relays_2 = relays->addAction("/DOM810 单板卡-非OK");
relays_2->setData(kCardRelayTMRPrimary); relays_2->setData(kCardRelaySingleNOK);
QAction *relays_3 = relays->addAction("/DOM810 三冗余板卡");
relays_3->setData(kCardRelayTMRPrimary);
// 将子菜单加入上一级菜单 // 将子菜单加入上一级菜单
monitors->addMenu(proximitor_menu); // 将第二层加入第一层 monitors->addMenu(proximitor_menu); // 将第二层加入第一层
monitors->addMenu(rpm_menu); // 第二层另一个子菜单 monitors->addMenu(rpm_menu); // 第二层另一个子菜单
@ -348,6 +352,11 @@ void MainWindow::onMenuActionTriggered() {
map_slot_config[button_id].rack_type = "Single"; map_slot_config[button_id].rack_type = "Single";
map_slot_config[button_id].chan_display = chan_display; map_slot_config[button_id].chan_display = chan_display;
button->setText(chan_display); button->setText(chan_display);
}else if (rack_type == "单板卡-非OK" && map_slot_config[button_id].slot_type == "") {
map_slot_config[button_id].slot_type = slot_type;
map_slot_config[button_id].rack_type = "Single";
map_slot_config[button_id].chan_display = chan_display;
button->setText(chan_display);
} }
if (action->text() == "重置模块") { if (action->text() == "重置模块") {
if (ConfigMgr::Instance()->card_type_[button_id - 1] == kCardRelayTMRPrimary) { if (ConfigMgr::Instance()->card_type_[button_id - 1] == kCardRelayTMRPrimary) {
@ -381,6 +390,11 @@ void MainWindow::onMenuActionTriggered() {
ConfigMgr::Instance()->card_type_[button_id - 1] == kCardKeyphaseSingle) { ConfigMgr::Instance()->card_type_[button_id - 1] == kCardKeyphaseSingle) {
ConfigMgr::Instance()->card_type_[button_id - 1] = kCardNone; ConfigMgr::Instance()->card_type_[button_id - 1] = kCardNone;
map_slot_config[button_id].slot_btn->setText(""); map_slot_config[button_id].slot_btn->setText("");
}else if (ConfigMgr::Instance()->card_type_[button_id - 1] == kCardRelaySingle ||
ConfigMgr::Instance()->card_type_[button_id - 1] == kCardRelaySingleNOK ||
ConfigMgr::Instance()->card_type_[button_id - 1] == kCardRelayTMRPrimary) {
ConfigMgr::Instance()->card_type_[button_id - 1] = kCardNone;
map_slot_config[button_id].slot_btn->setText("");
} }
} else if (action->text() == "升级固件") { } else if (action->text() == "升级固件") {
sendUpgradePackage(button_id); sendUpgradePackage(button_id);
@ -410,9 +424,20 @@ void MainWindow::OnButtonGroup(QAbstractButton *slot_btn) {
key_phase->setWindowModality(Qt::ApplicationModal); key_phase->setWindowModality(Qt::ApplicationModal);
key_phase->show(); key_phase->show();
} else if (slot_config.slot_type == "DOM810") { // 继电器模块 } else if (slot_config.slot_type == "DOM810") { // 继电器模块
SingleRelay *single_relay = new SingleRelay(); switch (card_type) {
single_relay->setWindowModality(Qt::ApplicationModal); case kCardRelaySingle:
single_relay->show(); case kCardRelayTMRPrimary:{
TMRRelayAssociation *single_tmr_relay = new TMRRelayAssociation(button_id,card_type);
single_tmr_relay->setWindowModality(Qt::ApplicationModal);
single_tmr_relay->show();
}break;
case kCardRelaySingleNOK:{
SingleRelay *single_relay = new SingleRelay(button_id,card_type);
single_relay->setWindowModality(Qt::ApplicationModal);
single_relay->show();
}break;
}
} else if (slot_config.slot_type == "HAM824") { // 振动模块 } else if (slot_config.slot_type == "HAM824") { // 振动模块
Seismic_monitor *seismic_monitor = new Seismic_monitor(button_id,card_type); Seismic_monitor *seismic_monitor = new Seismic_monitor(button_id,card_type);
seismic_monitor->setWindowModality(Qt::ApplicationModal); seismic_monitor->setWindowModality(Qt::ApplicationModal);
@ -437,14 +462,44 @@ void MainWindow::OnButtonGroup(QAbstractButton *slot_btn) {
key_phase->show(); key_phase->show();
break; break;
} }
case kCardRelaySingleNOK:{
SingleRelay *single_relay = new SingleRelay(button_id,card_type);
single_relay->setWindowModality(Qt::ApplicationModal);
single_relay->show();
break;
}
case kCardRelaySingle:
case kCardRelayTMRPrimary:{
TMRRelayAssociation *single_tmr_relay = new TMRRelayAssociation(button_id,card_type);
single_tmr_relay->setWindowModality(Qt::ApplicationModal);
single_tmr_relay->show();
break;
}
} }
} }
if (slot_btn != NULL && ui->pushButton_alarm->isChecked()) { if (slot_btn != NULL && ui->pushButton_alarm->isChecked()) {
QString object_name = slot_btn->objectName(); QString object_name = slot_btn->objectName();
int button_id = object_name.right(object_name.length() - 15).toInt(); int button_id = object_name.right(object_name.length() - 15).toInt();
Setpoint *setpoint = new Setpoint(button_id,ConfigMgr::Instance()->card_type_[button_id]); std::shared_ptr<CardBase> base_ptr = ConfigMgr::Instance()->GetSlotPtr(button_id);
setpoint->setWindowModality(Qt::ApplicationModal); switch(base_ptr->card_type_){
setpoint->show(); case kCardVibSingle:{
QString object_name = slot_btn->objectName();
int button_id = object_name.right(object_name.length() - 15).toInt();
Setpoint *setpoint = new Setpoint(button_id,ConfigMgr::Instance()->card_type_[button_id - 1]);
setpoint->setWindowModality(Qt::ApplicationModal);
setpoint->show();
break;
}
case kCardSpeedSingle:{
QString object_name = slot_btn->objectName();
int button_id = object_name.right(object_name.length() - 15).toInt();
Setpoint_Tachometer *setpoint_tachometer = new Setpoint_Tachometer(button_id,ConfigMgr::Instance()->card_type_[button_id - 1]);
setpoint_tachometer->setWindowModality(Qt::ApplicationModal);
setpoint_tachometer->show();
break;
}
}
} }
} }
@ -602,6 +657,12 @@ void MainWindow::on_pushButton_open_clicked() {
buttonList[i + 1]->setText("转速"); buttonList[i + 1]->setText("转速");
break; break;
} }
case kCardRelaySingle:
case kCardRelaySingleNOK:
case kCardRelayTMRPrimary:{
buttonList[i + 1]->setText("继电器");
break;
}
default: default:
break; break;
} }

View File

@ -2,10 +2,12 @@
#include <QPainter> #include <QPainter>
#include <QMouseEvent> #include <QMouseEvent>
#include <QDebug> #include <QDebug>
#include <cmath>
RangeSlider::RangeSlider(int style,QWidget *parent) RangeSlider::RangeSlider(int style_,QWidget *parent)
: QWidget(parent) { : QWidget(parent) {
setMinimumSize(20, 240); setMinimumSize(20, 240);
style = style_;
} }
void RangeSlider::setRange(int min, int max) { void RangeSlider::setRange(int min, int max) {
@ -83,11 +85,10 @@ void RangeSlider::paintEvent(QPaintEvent *) {
p.setBrush(Qt::green); p.setBrush(Qt::green);
p.drawRect(x - sliderWidth / 2, yUpper, sliderWidth, yLower - yUpper); p.drawRect(x - sliderWidth / 2, yUpper, sliderWidth, yLower - yUpper);
// Draw simple red handles (circles) // Draw simple black handles (lines)
p.setPen(Qt::NoPen); p.setPen(QPen(Qt::black, 2));
p.setBrush(Qt::red); p.drawLine(x - sliderWidth / 2, yLower, x + sliderWidth, yLower);
p.drawEllipse(QPointF(x, yLower), handleRadius, handleRadius); p.drawLine(x - sliderWidth / 2, yUpper, x + sliderWidth, yUpper);
p.drawEllipse(QPointF(x, yUpper), handleRadius, handleRadius);
// Draw ticks // Draw ticks
drawTicks(&p); drawTicks(&p);
@ -114,25 +115,57 @@ void RangeSlider::drawTemperatureStyle(QPainter *p) {
p->drawRect(x - sliderWidth / 2, yTop, sliderWidth, yBottom - yTop); p->drawRect(x - sliderWidth / 2, yTop, sliderWidth, yBottom - yTop);
// Draw yellow outside the range // Draw yellow outside the range
p->setBrush(Qt::yellow); if(style != 0){
p->drawRect(x - sliderWidth / 2, yTop, sliderWidth, valueToY(m_lower) - yTop); // Above lower range p->setBrush(Qt::red);
p->drawRect(x - sliderWidth / 2, valueToY(m_upper), sliderWidth, yBottom - valueToY(m_upper)); // Below upper range p->drawRect(x - sliderWidth / 2, yTop, sliderWidth, valueToY(m_lower) - yTop); // Above lower range
p->drawRect(x - sliderWidth / 2, valueToY(m_upper), sliderWidth, yBottom - valueToY(m_upper)); // Below upper range
}else{
p->setBrush(Qt::yellow);
p->drawRect(x - sliderWidth / 2, yTop, sliderWidth, valueToY(m_lower) - yTop); // Above lower range
p->drawRect(x - sliderWidth / 2, valueToY(m_upper), sliderWidth, yBottom - valueToY(m_upper)); // Below upper range
}
// Draw green inside the range // Draw green inside the range
p->setBrush(Qt::green); p->setBrush(Qt::green);
p->drawRect(x - sliderWidth / 2, valueToY(m_upper), sliderWidth, valueToY(m_lower) - valueToY(m_upper)); // Green area p->drawRect(x - sliderWidth / 2, valueToY(m_upper), sliderWidth, valueToY(m_lower) - valueToY(m_upper)); // Green area
} }
int RangeSlider::niceStep(int range, int maxLabels) {
double rawStep = static_cast<double>(range) / maxLabels;
// 取一个"好看"的步长
double magnitude = pow(10, floor(log10(rawStep))); // 10 的整数次幂
double residual = rawStep / magnitude;
double niceResidual;
if (residual < 1.5)
niceResidual = 1;
else if (residual < 3)
niceResidual = 2;
else if (residual < 7)
niceResidual = 5;
else
niceResidual = 10;
return static_cast<int>(niceResidual * magnitude);
}
void RangeSlider::drawTicks(QPainter *p) { void RangeSlider::drawTicks(QPainter *p) {
int tickCount = 11; int range = m_max - m_min;
p->setPen(Qt::black); int labelStep = niceStep(range, 10);
p->setFont(QFont("Arial", 8)); int minorStep = qMax(1, labelStep / 5);
int x = width() / 2 + handleRadius + 4;
for (int i = 0; i < tickCount; ++i) { int x = width() / 2 + handleRadius + 4;
int val = m_min + i * (m_max - m_min) / (tickCount - 1); p->setFont(QFont("Arial", 8));
for (int val = m_min; val <= m_max; val += minorStep) {
int y = valueToY(val); int y = valueToY(val);
p->drawLine(x, y, x + 3, y); // 刻度宽度
p->drawText(x + 8, y + 4, QString::number(val)); if (val % labelStep == 0) {
p->setPen(QPen(Qt::black, 1.5)); // 主刻度
p->drawLine(x, y, x + 6, y);
p->drawText(x + 10, y + 4, QString::number(val));
} else {
p->setPen(QPen(Qt::gray, 1)); // 次刻度
p->drawLine(x, y, x + 3, y);
}
} }
} }

View File

@ -7,7 +7,7 @@ class RangeSlider : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit RangeSlider(int style = 0,QWidget *parent = nullptr); explicit RangeSlider(int style_ = 0,QWidget *parent = nullptr);
void setRange(int min, int max); void setRange(int min, int max);
void setSliderWidth(int width); // 新增方法:设置宽度 void setSliderWidth(int width); // 新增方法:设置宽度
@ -17,6 +17,7 @@ public:
void setUpperValue(float val); void setUpperValue(float val);
float m_lower = 3.5; float m_lower = 3.5;
float m_upper = 6.5; float m_upper = 6.5;
int style = 0;
signals: signals:
void rangeChanged(float lower, float upper); void rangeChanged(float lower, float upper);
@ -30,7 +31,7 @@ private:
float m_min = 0; float m_min = 0;
float m_max = 10; float m_max = 10;
int sliderWidth = 15; // 默认宽度(可以根据需求调整) int sliderWidth = 10; // 默认宽度(可以根据需求调整)
int handleRadius = 8; int handleRadius = 8;
enum HandleType { NoHandle, LowerHandle, UpperHandle }; enum HandleType { NoHandle, LowerHandle, UpperHandle };
@ -39,7 +40,7 @@ private:
float valueToY(float value) const; float valueToY(float value) const;
float yToValue(float y) const; float yToValue(float y) const;
HandleType handleHitTest(float y) const; HandleType handleHitTest(float y) const;
int niceStep(int range, int maxLabels);
void drawTicks(QPainter *p); void drawTicks(QPainter *p);
void drawTemperatureStyle(QPainter *p); void drawTemperatureStyle(QPainter *p);
}; };

View File

@ -13,6 +13,9 @@ Setpoint::Setpoint(int slot_no_,int cardtype,QWidget *parent) :
ui->label_slot->setText(QString::number(slot_no)); ui->label_slot->setText(QString::number(slot_no));
Init(); Init();
connect(ui->comboBox_chan, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &Setpoint::onComboBoxIndexChanged);
current_index = ui->comboBox_chan->currentIndex();
} }
Setpoint::~Setpoint() Setpoint::~Setpoint()
@ -42,11 +45,11 @@ void Setpoint::Init(){
layout_2x_ampl->addWidget(slider_2x_ampl); layout_2x_ampl->addWidget(slider_2x_ampl);
QVBoxLayout *layout_danger = new QVBoxLayout(ui->widget_danger); QVBoxLayout *layout_danger = new QVBoxLayout(ui->widget_danger);
slider_danger = new RangeSlider; slider_danger = new RangeSlider(1);
layout_danger->addWidget(slider_danger); layout_danger->addWidget(slider_danger);
std::shared_ptr<CardBase> base_ptr = ConfigMgr::Instance()->GetSlotPtr(slot_no); std::shared_ptr<CardBase> base_ptr = ConfigMgr::Instance()->GetSlotPtr(slot_no);
vib_alert_ptr = std::dynamic_pointer_cast<VibrationData>(base_ptr);
switch (car_type) { switch (car_type) {
case kCardVibSingle:{ case kCardVibSingle:{
@ -56,22 +59,31 @@ void Setpoint::Init(){
slider_danger->setRange(0,20); slider_danger->setRange(0,20);
int chan = ui->comboBox_chan->currentIndex(); int chan = ui->comboBox_chan->currentIndex();
std::shared_ptr<VibrationData> setpoint_data = std::dynamic_pointer_cast<VibrationData>(base_ptr); std::shared_ptr<VibrationData> setpoint_data = std::dynamic_pointer_cast<VibrationData>(base_ptr);
ui->lineEdit_direct_upper->setText(QString::number(setpoint_data->vib_alert_danger[chan].direct_upper)); ui->lineEdit_direct_upper->setText(QString::number(setpoint_data->alert_danger[chan].direct_upper));
ui->checkBox_direct->setChecked(setpoint_data->vib_alert_danger[chan].direct_enable); ui->checkBox_direct->setChecked(setpoint_data->alert_danger[chan].direct_enable);
slider_direct->m_upper = setpoint_data->vib_alert_danger[chan].direct_upper; if(setpoint_data->alert_danger[chan].direct_upper > 0){
ui->lineEdit_1x_ampl_upper->setText(QString::number(setpoint_data->vib_alert_danger[chan].x1_ampl_upper)); slider_direct->m_upper = setpoint_data->alert_danger[chan].direct_upper;
ui->lineEdit_1x_ampl_lower->setText(QString::number(setpoint_data->vib_alert_danger[chan].x1_ampl_lower)); }
ui->checkBox_1x_ampl->setChecked(setpoint_data->vib_alert_danger[chan].x1_ampl_enable); ui->lineEdit_1x_ampl_upper->setText(QString::number(setpoint_data->alert_danger[chan].x1_ampl_upper));
slider_1x_ampl->m_upper = setpoint_data->vib_alert_danger[chan].x1_ampl_upper; ui->lineEdit_1x_ampl_lower->setText(QString::number(setpoint_data->alert_danger[chan].x1_ampl_lower));
slider_1x_ampl->m_lower = setpoint_data->vib_alert_danger[chan].x1_ampl_lower; ui->checkBox_1x_ampl->setChecked(setpoint_data->alert_danger[chan].x1_ampl_enable);
ui->lineEdit_2x_ampl_upper->setText(QString::number(setpoint_data->vib_alert_danger[chan].x2_ampl_upper)); if(setpoint_data->alert_danger[chan].x1_ampl_upper > 0 && setpoint_data->alert_danger[chan].x1_ampl_lower > 0){
ui->lineEdit_2x_ampl_lower->setText(QString::number(setpoint_data->vib_alert_danger[chan].x2_ampl_lower)); slider_1x_ampl->m_upper = setpoint_data->alert_danger[chan].x1_ampl_upper;
ui->checkBox_2x_ampl->setChecked(setpoint_data->vib_alert_danger[chan].x2_ampl_enable); slider_1x_ampl->m_lower = setpoint_data->alert_danger[chan].x1_ampl_lower;
slider_2x_ampl->m_upper = setpoint_data->vib_alert_danger[chan].x2_ampl_upper; }
slider_2x_ampl->m_lower = setpoint_data->vib_alert_danger[chan].x2_ampl_lower; ui->lineEdit_2x_ampl_upper->setText(QString::number(setpoint_data->alert_danger[chan].x2_ampl_upper));
ui->lineEdit_danger_upper->setText(QString::number(setpoint_data->vib_alert_danger[chan].danger_upper)); ui->lineEdit_2x_ampl_lower->setText(QString::number(setpoint_data->alert_danger[chan].x2_ampl_lower));
ui->checkBox_danger->setChecked(setpoint_data->vib_alert_danger[chan].danger_enable); ui->checkBox_2x_ampl->setChecked(setpoint_data->alert_danger[chan].x2_ampl_enable);
slider_danger->m_upper = setpoint_data->vib_alert_danger[chan].danger_upper; if(setpoint_data->alert_danger[chan].x2_ampl_upper > 0 && setpoint_data->alert_danger[chan].x2_ampl_lower > 0){
slider_2x_ampl->m_upper = setpoint_data->alert_danger[chan].x2_ampl_upper;
slider_2x_ampl->m_lower = setpoint_data->alert_danger[chan].x2_ampl_lower;
}
ui->lineEdit_danger_upper->setText(QString::number(setpoint_data->alert_danger[chan].danger_upper));
ui->checkBox_danger->setChecked(setpoint_data->alert_danger[chan].danger_enable);
if(setpoint_data->alert_danger[chan].danger_upper > 0){
slider_danger->m_upper = setpoint_data->alert_danger[chan].danger_upper;
slider_danger->m_lower = 0;
}
}break; }break;
case kCardSpeedSingle:{ case kCardSpeedSingle:{
slider_direct->setRange(0,5000); slider_direct->setRange(0,5000);
@ -117,24 +129,22 @@ void Setpoint::Init(){
void Setpoint::on_pushButton_confirm_clicked() void Setpoint::on_pushButton_confirm_clicked()
{ {
std::shared_ptr<CardBase> base_ptr = ConfigMgr::Instance()->GetSlotPtr(slot_no); if (vib_alert_ptr == nullptr) {
if (base_ptr == nullptr) {
qCritical() << "[Setpoint::confirm] should not be here"; qCritical() << "[Setpoint::confirm] should not be here";
return; return;
} }
int chan = ui->comboBox_chan->currentIndex();
std::shared_ptr<VibrationData> ptr = std::dynamic_pointer_cast<VibrationData>(base_ptr); vib_alert_ptr->alert_danger[current_index].direct_upper = ui->lineEdit_direct_upper->text().toFloat();
ptr->vib_alert_danger[chan].direct_upper = ui->lineEdit_direct_upper->text().toFloat(); vib_alert_ptr->alert_danger[current_index].direct_enable = ui->checkBox_direct->checkState();
ptr->vib_alert_danger[chan].direct_enable = ui->checkBox_direct->checkState(); vib_alert_ptr->alert_danger[current_index].x1_ampl_upper = ui->lineEdit_1x_ampl_upper->text().toFloat();
ptr->vib_alert_danger[chan].x1_ampl_upper = ui->lineEdit_1x_ampl_upper->text().toFloat(); vib_alert_ptr->alert_danger[current_index].x1_ampl_lower = ui->lineEdit_1x_ampl_lower->text().toFloat();
ptr->vib_alert_danger[chan].x1_ampl_lower = ui->lineEdit_1x_ampl_lower->text().toFloat(); vib_alert_ptr->alert_danger[current_index].x1_ampl_enable = ui->checkBox_1x_ampl->checkState();
ptr->vib_alert_danger[chan].x1_ampl_enable = ui->checkBox_1x_ampl->checkState(); vib_alert_ptr->alert_danger[current_index].x2_ampl_upper = ui->lineEdit_2x_ampl_upper->text().toFloat();
ptr->vib_alert_danger[chan].x2_ampl_upper = ui->lineEdit_2x_ampl_upper->text().toFloat(); vib_alert_ptr->alert_danger[current_index].x2_ampl_lower = ui->lineEdit_2x_ampl_lower->text().toFloat();
ptr->vib_alert_danger[chan].x2_ampl_lower = ui->lineEdit_2x_ampl_lower->text().toFloat(); vib_alert_ptr->alert_danger[current_index].x2_ampl_enable = ui->checkBox_2x_ampl->checkState();
ptr->vib_alert_danger[chan].x2_ampl_enable = ui->checkBox_2x_ampl->checkState(); vib_alert_ptr->alert_danger[current_index].danger_param = ui->comboBox_danger->currentIndex();
ptr->vib_alert_danger[chan].danger_param = ui->comboBox_danger->currentIndex(); vib_alert_ptr->alert_danger[current_index].danger_upper = ui->lineEdit_danger_upper->text().toFloat();
ptr->vib_alert_danger[chan].danger_upper = ui->lineEdit_danger_upper->text().toFloat(); vib_alert_ptr->alert_danger[current_index].danger_enable = ui->checkBox_danger->checkState();
ptr->vib_alert_danger[chan].danger_enable = ui->checkBox_danger->checkState();
this->close(); this->close();
} }
@ -149,4 +159,43 @@ void Setpoint::on_pushButton_set_default_clicked()
{ {
} }
void Setpoint::onComboBoxIndexChanged(int index){
vib_alert_ptr->alert_danger[current_index].direct_upper = ui->lineEdit_direct_upper->text().toFloat();
vib_alert_ptr->alert_danger[current_index].direct_enable = ui->checkBox_direct->checkState();
vib_alert_ptr->alert_danger[current_index].x1_ampl_upper = ui->lineEdit_1x_ampl_upper->text().toFloat();
vib_alert_ptr->alert_danger[current_index].x1_ampl_lower = ui->lineEdit_1x_ampl_lower->text().toFloat();
vib_alert_ptr->alert_danger[current_index].x1_ampl_enable = ui->checkBox_1x_ampl->checkState();
vib_alert_ptr->alert_danger[current_index].x2_ampl_upper = ui->lineEdit_2x_ampl_upper->text().toFloat();
vib_alert_ptr->alert_danger[current_index].x2_ampl_lower = ui->lineEdit_2x_ampl_lower->text().toFloat();
vib_alert_ptr->alert_danger[current_index].x2_ampl_enable = ui->checkBox_2x_ampl->checkState();
vib_alert_ptr->alert_danger[current_index].danger_param = ui->comboBox_danger->currentIndex();
vib_alert_ptr->alert_danger[current_index].danger_upper = ui->lineEdit_danger_upper->text().toFloat();
vib_alert_ptr->alert_danger[current_index].danger_enable = ui->checkBox_danger->checkState();
current_index = index;
ui->lineEdit_direct_upper->setText(QString::number(vib_alert_ptr->alert_danger[index].direct_upper));
ui->checkBox_direct->setChecked(vib_alert_ptr->alert_danger[index].direct_enable);
if(vib_alert_ptr->alert_danger[index].direct_upper > 0)
slider_direct->m_upper = vib_alert_ptr->alert_danger[index].direct_upper;
ui->lineEdit_1x_ampl_upper->setText(QString::number(vib_alert_ptr->alert_danger[index].x1_ampl_upper));
ui->lineEdit_1x_ampl_lower->setText(QString::number(vib_alert_ptr->alert_danger[index].x1_ampl_lower));
ui->checkBox_1x_ampl->setChecked(vib_alert_ptr->alert_danger[index].x1_ampl_enable);
if(vib_alert_ptr->alert_danger[index].x1_ampl_upper > 0 && vib_alert_ptr->alert_danger[index].x1_ampl_lower > 0){
slider_1x_ampl->m_upper = vib_alert_ptr->alert_danger[index].x1_ampl_upper;
slider_1x_ampl->m_lower = vib_alert_ptr->alert_danger[index].x1_ampl_lower;
}
ui->lineEdit_2x_ampl_upper->setText(QString::number(vib_alert_ptr->alert_danger[index].x2_ampl_upper));
ui->lineEdit_2x_ampl_lower->setText(QString::number(vib_alert_ptr->alert_danger[index].x2_ampl_lower));
ui->checkBox_2x_ampl->setChecked(vib_alert_ptr->alert_danger[index].x2_ampl_enable);
if(vib_alert_ptr->alert_danger[index].x2_ampl_upper > 0 && vib_alert_ptr->alert_danger[index].x2_ampl_lower > 0){
slider_2x_ampl->m_upper = vib_alert_ptr->alert_danger[index].x2_ampl_upper;
slider_2x_ampl->m_lower = vib_alert_ptr->alert_danger[index].x2_ampl_lower;
}
ui->lineEdit_danger_upper->setText(QString::number(vib_alert_ptr->alert_danger[index].danger_upper));
ui->checkBox_danger->setChecked(vib_alert_ptr->alert_danger[index].danger_enable);
if(vib_alert_ptr->alert_danger[index].danger_upper > 0){
slider_danger->m_upper = vib_alert_ptr->alert_danger[index].danger_upper;
}
}

View File

@ -26,12 +26,16 @@ private slots:
void on_pushButton_set_default_clicked(); void on_pushButton_set_default_clicked();
void onComboBoxIndexChanged(int index);
private: private:
Ui::Setpoint *ui; Ui::Setpoint *ui;
RangeSlider *slider_direct; RangeSlider *slider_direct;
RangeSlider *slider_1x_ampl; RangeSlider *slider_1x_ampl;
RangeSlider *slider_2x_ampl; RangeSlider *slider_2x_ampl;
RangeSlider *slider_danger; RangeSlider *slider_danger;
std::shared_ptr<VibrationData> vib_alert_ptr = nullptr;
int current_index;
void Init(); void Init();
}; };

View File

@ -106,19 +106,19 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>116</y> <y>116</y>
<width>80</width> <width>100</width>
<height>260</height> <height>260</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>80</width> <width>100</width>
<height>260</height> <height>260</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>80</width> <width>100</width>
<height>260</height> <height>260</height>
</size> </size>
</property> </property>

View File

@ -1,21 +1,121 @@
#include "singlerelay.h" #include "singlerelay.h"
#include "ui_singlerelay.h" #include "ui_singlerelay.h"
SingleRelay::SingleRelay(QWidget *parent)
SingleRelay::SingleRelay(int slot,int cardtype,QWidget *parent)
: QDialog(parent) : QDialog(parent)
, ui(new Ui::SingleRelay) { , ui(new Ui::SingleRelay) {
ui->setupUi(this); ui->setupUi(this);
slot_no = slot;
car_type = static_cast<CardType>(cardtype);
ui->label_slot_no->setText(QString::number(slot_no));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
QVBoxLayout *layout = new QVBoxLayout(ui->widget_relay); QVBoxLayout *layout_relay = new QVBoxLayout(ui->widget_relay);
DropTextEdit *textEdit = new DropTextEdit; textEdit_relay = new DropTextEdit;
layout_relay->addWidget(textEdit_relay);
QVBoxLayout *layout_available = new QVBoxLayout(ui->widget_available);
list_widget_available = new DraggableListWidget;
layout_available->addWidget(list_widget_available);
layout->addWidget(textEdit); btnGroup_slot = new QButtonGroup(this);
btnGroup_slot->addButton(ui->pushButton_slot1);
btnGroup_slot->addButton(ui->pushButton_slot2);
btnGroup_slot->addButton(ui->pushButton_slot3);
btnGroup_slot->addButton(ui->pushButton_slot4);
btnGroup_slot->addButton(ui->pushButton_slot5);
btnGroup_slot->addButton(ui->pushButton_slot6);
btnGroup_slot->addButton(ui->pushButton_slot7);
btnGroup_slot->addButton(ui->pushButton_slot8);
btnGroup_slot->addButton(ui->pushButton_slot9);
btnGroup_slot->addButton(ui->pushButton_slot10);
btnGroup_slot->addButton(ui->pushButton_slot11);
btnGroup_slot->addButton(ui->pushButton_slot12);
btnGroup_slot->addButton(ui->pushButton_slot13);
btnGroup_slot->addButton(ui->pushButton_slot14);
btnGroup_slot->addButton(ui->pushButton_slot15);
btnGroup_slot->addButton(ui->pushButton_slot16);
connect(btnGroup_slot, SIGNAL(buttonClicked(QAbstractButton *)), this, SLOT(OnButtonGroup(QAbstractButton *)));
connect(ui->pushButton_backspace, &QPushButton::clicked, textEdit_relay, &DropTextEdit::removeLastElement);
connect(ui->comboBox_relay_ch, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &SingleRelay::onComboBoxIndexChanged);
Init();
current_index = ui->comboBox_relay_ch->currentIndex();
if(single_relay_nok_data->single_relay_nok[current_index].logic_expression != "")
textEdit_relay->setPlainText(single_relay_nok_data->single_relay_nok[current_index].logic_expression);
} }
SingleRelay::~SingleRelay() { SingleRelay::~SingleRelay() {
delete ui; delete ui;
} }
void SingleRelay::Init(){
std::shared_ptr<CardBase> base_ptr = ConfigMgr::Instance()->GetSlotPtr(slot_no);
if (base_ptr == nullptr) {
// do nothing or use template to init it.
single_relay_nok_data = std::make_shared<SingleRelayDataNOK>();
single_relay_nok_data->card_type_ = car_type;
single_relay_nok_data->slot_ = slot_no;
ConfigMgr::Instance()->AddCard(single_relay_nok_data);
return;
}
single_relay_nok_data = std::dynamic_pointer_cast<SingleRelayDataNOK>(base_ptr);
}
void SingleRelay::on_pushButton_cancel_clicked() { void SingleRelay::on_pushButton_cancel_clicked() {
this->close(); this->close();
} }
void SingleRelay::OnButtonGroup(QAbstractButton *slot_btn) {
if (slot_btn != NULL) {
list_widget_available->clear();
QString object_name = slot_btn->objectName();
qDebug() << object_name ;
int button_id = object_name.right(object_name.length() - 15).toInt();
for(int var = 0; var < CHANNEL_COUNT ; ++var){
QString item_str = QString("S%1C%2P##NO (Slot %3 Channel %4 Not OK)").arg(QString::number(button_id, 10).rightJustified(2, '0')).arg(QString::number(var+1, 10).rightJustified(2, '0')).arg(button_id).arg(var+1);
QListWidgetItem *item = new QListWidgetItem(item_str);
QString item_data = QString("S%1C%2P##NO").arg(QString::number(button_id, 10).rightJustified(2, '0')).arg(QString::number(var+1, 10).rightJustified(2, '0'));
item->setData(Qt::UserRole, item_data);
list_widget_available->addItem(item);
}
}
}
void SingleRelay::on_pushButton_enter_clicked()
{
}
void SingleRelay::on_pushButton_clr_clicked()
{
textEdit_relay->setText("");
}
void SingleRelay::on_pushButton_backspace_clicked()
{
}
void SingleRelay::keyPressEvent(QKeyEvent *event) {
// if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
// removeLastElement();
// return;
// }
// QTextEdit::keyPressEvent(event);
}
void SingleRelay::on_pushButton_confirm_clicked()
{
single_relay_nok_data->single_relay_nok[current_index].logic_expression = textEdit_relay->toPlainText();
this->close();
}
void SingleRelay::onComboBoxIndexChanged(int index){
qDebug()<< "[SingleRelay]:index " << index;
single_relay_nok_data->single_relay_nok[current_index].logic_expression = textEdit_relay->toPlainText();
current_index = index;
textEdit_relay->setPlainText(single_relay_nok_data->single_relay_nok[index].logic_expression);
}

View File

@ -3,39 +3,72 @@
#include <QDialog> #include <QDialog>
#include <QTextEdit> #include <QTextEdit>
#include <QMimeData> #include <QButtonGroup>
#include <QDrag> #include <QPushButton>
#include <QDragEnterEvent> #include "data_config.h"
#include <QDebug> #include "config_mgr.h"
#include "singlerelay_data.h"
namespace Ui { namespace Ui {
class SingleRelay; class SingleRelay;
} }
class SingleRelay : public QDialog {
Q_OBJECT
public:
explicit SingleRelay(QWidget *parent = nullptr);
~SingleRelay();
private slots:
void on_pushButton_cancel_clicked();
private:
Ui::SingleRelay *ui;
};
class DropTextEdit : public QTextEdit { class DropTextEdit : public QTextEdit {
Q_OBJECT
public: public:
DropTextEdit(QWidget *parent = nullptr) : QTextEdit(parent) { DropTextEdit(QWidget *parent = nullptr) : QTextEdit(parent) {
setAcceptDrops(true); setAcceptDrops(true);
setReadOnly(false); // 确保不是只读的
} }
public slots:
void removeLastElement() {
QString html = this->toHtml();
// 匹配 <span>元素</span>
QRegularExpression spanRe(R"(<span[^>]*>[^<]*</span>)");
QRegularExpressionMatchIterator spanIt = spanRe.globalMatch(html);
// 匹配符号元素(注意符号两边可能有空格)
QRegularExpression symbolRe(R"((\s?[+*()]\s?))");
QRegularExpressionMatchIterator symbolIt = symbolRe.globalMatch(html);
// 保存所有匹配结果:位置 + 匹配内容
struct Match {
int start;
int length;
};
QList<Match> matches;
while (spanIt.hasNext()) {
auto m = spanIt.next();
matches.append({ m.capturedStart(), m.capturedLength() });
}
while (symbolIt.hasNext()) {
auto m = symbolIt.next();
matches.append({ m.capturedStart(), m.capturedLength() });
}
if (matches.isEmpty())
return;
// 找出最后出现的元素
std::sort(matches.begin(), matches.end(), [](const Match &a, const Match &b) {
return a.start < b.start;
});
// 删除最后一个匹配
Match last = matches.last();
html.remove(last.start, last.length);
this->setHtml(html);
// 保持光标在末尾
QTextCursor cursor = this->textCursor();
cursor.movePosition(QTextCursor::End);
this->setTextCursor(cursor);
}
protected: protected:
void dragEnterEvent(QDragEnterEvent *event) override { void dragEnterEvent(QDragEnterEvent *event) override {
qDebug() << "dragEnterEvent" << event->mimeData()->formats(); if (event->mimeData()->hasFormat("application/x-custom")) {
if (event->mimeData()->hasText()) {
event->acceptProposedAction(); event->acceptProposedAction();
} else { } else {
event->ignore(); event->ignore();
@ -43,7 +76,7 @@ protected:
} }
void dragMoveEvent(QDragMoveEvent *event) override { void dragMoveEvent(QDragMoveEvent *event) override {
if (event->mimeData()->hasText()) { if (event->mimeData()->hasFormat("application/x-custom")) {
event->acceptProposedAction(); event->acceptProposedAction();
} else { } else {
event->ignore(); event->ignore();
@ -51,12 +84,66 @@ protected:
} }
void dropEvent(QDropEvent *event) override { void dropEvent(QDropEvent *event) override {
if (event->mimeData()->hasText()) { if (!this->toPlainText().isEmpty()) {
insertPlainText(event->mimeData()->text()); event->ignore();
return;
}
if (event->mimeData()->hasFormat("application/x-custom")) {
QByteArray data = event->mimeData()->data("application/x-custom");
QString text = QString::fromUtf8(data);
QTextCursor cursor = this->textCursor();
this->setTextCursor(cursor);
QString html = QString(
"<span style='"
"background:#ddd;"
"padding:2px 6px;"
"border-radius:4px;"
"border:1px solid #aaa;"
"outline: none;"
"box-shadow: none;"
"text-shadow: none;"
"display:inline-block;'>%1</span>"
).arg(text);
cursor.insertHtml(html);
event->acceptProposedAction(); event->acceptProposedAction();
} else { } else {
event->ignore(); event->ignore();
} }
} }
}; };
class SingleRelay : public QDialog {
Q_OBJECT
public:
explicit SingleRelay(int slot,int cardtype,QWidget *parent = nullptr);
~SingleRelay();
int slot_no;
CardType car_type;
private slots:
void keyPressEvent(QKeyEvent *event);
void on_pushButton_cancel_clicked();
void OnButtonGroup(QAbstractButton *);
void on_pushButton_enter_clicked();
void on_pushButton_backspace_clicked();
void on_pushButton_clr_clicked();
void on_pushButton_confirm_clicked();
void onComboBoxIndexChanged(int index);
private:
Ui::SingleRelay *ui;
QButtonGroup * btnGroup_slot = nullptr;
DraggableListWidget *list_widget_available = nullptr;
DropTextEdit *textEdit_relay = nullptr;
std::shared_ptr<SingleRelayDataNOK> single_relay_nok_data = nullptr;
int current_index;
void Init();
};
#endif // SINGLERELAY_H #endif // SINGLERELAY_H

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>943</width> <width>924</width>
<height>569</height> <height>569</height>
</rect> </rect>
</property> </property>
@ -26,7 +26,7 @@
<string>告警驱动逻辑:</string> <string>告警驱动逻辑:</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="pushButton_10"> <widget class="QPushButton" name="pushButton_confirm">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>220</x> <x>220</x>
@ -52,24 +52,11 @@
<string>NCT6100T</string> <string>NCT6100T</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>690</x>
<y>230</y>
<width>61</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>或(*)</string>
</property>
</widget>
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>620</x> <x>620</x>
<y>30</y> <y>10</y>
<width>111</width> <width>111</width>
<height>16</height> <height>16</height>
</rect> </rect>
@ -78,13 +65,13 @@
<string>可用的告警:</string> <string>可用的告警:</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="pushButton_9"> <widget class="QPushButton" name="pushButton_print">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>510</x> <x>420</x>
<y>530</y> <y>530</y>
<width>71</width> <width>71</width>
<height>32</height> <height>32</height>
@ -94,42 +81,6 @@
<string>打 印...</string> <string>打 印...</string>
</property> </property>
</widget> </widget>
<widget class="QListWidget" name="listWidget_available">
<property name="geometry">
<rect>
<x>620</x>
<y>50</y>
<width>301</width>
<height>161</height>
</rect>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<item>
<property name="text">
<string>S02C01P##NO (Slot 2 Channel 1 Not OK)</string>
</property>
</item>
<item>
<property name="text">
<string>S02C02P##NO (Slot 2 Channel 2 Not OK)</string>
</property>
</item>
<item>
<property name="text">
<string>S02C03P##NO (Slot 2 Channel 3 Not OK)</string>
</property>
</item>
<item>
<property name="text">
<string>S02C04P##NO (Slot 2 Channel 4 Not OK)</string>
</property>
</item>
</widget>
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="groupBox_2">
<property name="geometry"> <property name="geometry">
<rect> <rect>
@ -142,7 +93,7 @@
<property name="title"> <property name="title">
<string>继电器关联</string> <string>继电器关联</string>
</property> </property>
<widget class="QComboBox" name="comboBox"> <widget class="QComboBox" name="comboBox_relay_ch">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>20</x> <x>20</x>
@ -259,58 +210,6 @@
</property> </property>
</widget> </widget>
</widget> </widget>
<widget class="QPushButton" name="pushButton_4">
<property name="geometry">
<rect>
<x>690</x>
<y>270</y>
<width>61</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>)</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit">
<property name="geometry">
<rect>
<x>113</x>
<y>9</y>
<width>31</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string> 13</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>620</x>
<y>230</y>
<width>61</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>与(*)</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_3">
<property name="geometry">
<rect>
<x>620</x>
<y>270</y>
<width>61</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="geometry"> <property name="geometry">
<rect> <rect>
@ -324,10 +223,10 @@
<string>继电器槽位:</string> <string>继电器槽位:</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="pushButton_5"> <widget class="QPushButton" name="pushButton_enter">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>760</x> <x>630</x>
<y>230</y> <y>230</y>
<width>61</width> <width>61</width>
<height>71</height> <height>71</height>
@ -337,13 +236,13 @@
<string>Enter</string> <string>Enter</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="pushButton_12"> <widget class="QPushButton" name="pushButton_help">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>600</x> <x>520</x>
<y>530</y> <y>530</y>
<width>81</width> <width>81</width>
<height>32</height> <height>32</height>
@ -353,10 +252,10 @@
<string>帮 助</string> <string>帮 助</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="pushButton_7"> <widget class="QPushButton" name="pushButton_clr">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>850</x> <x>710</x>
<y>270</y> <y>270</y>
<width>61</width> <width>61</width>
<height>31</height> <height>31</height>
@ -366,10 +265,10 @@
<string>CLR</string> <string>CLR</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="pushButton_6"> <widget class="QPushButton" name="pushButton_backspace">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>850</x> <x>710</x>
<y>230</y> <y>230</y>
<width>61</width> <width>61</width>
<height>31</height> <height>31</height>
@ -382,7 +281,7 @@
<widget class="QPushButton" name="pushButton_cancel"> <widget class="QPushButton" name="pushButton_cancel">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>410</x> <x>320</x>
<y>530</y> <y>530</y>
<width>71</width> <width>71</width>
<height>32</height> <height>32</height>
@ -392,7 +291,7 @@
<string>取 消</string> <string>取 消</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="pushButton_8"> <widget class="QPushButton" name="pushButton_alert_signal">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>620</x> <x>620</x>
@ -777,7 +676,7 @@
<widget class="QWidget" name="widget_3" native="true"> <widget class="QWidget" name="widget_3" native="true">
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QPushButton" name="pushButton_17"> <widget class="QPushButton" name="pushButton_slot1">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -796,7 +695,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_18"> <widget class="QPushButton" name="pushButton_slot2">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -815,7 +714,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_20"> <widget class="QPushButton" name="pushButton_slot3">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -834,7 +733,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_19"> <widget class="QPushButton" name="pushButton_slot4">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -853,7 +752,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_24"> <widget class="QPushButton" name="pushButton_slot5">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -872,7 +771,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_23"> <widget class="QPushButton" name="pushButton_slot6">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -891,7 +790,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_22"> <widget class="QPushButton" name="pushButton_slot7">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -910,7 +809,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_21"> <widget class="QPushButton" name="pushButton_slot8">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -929,7 +828,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_32"> <widget class="QPushButton" name="pushButton_slot9">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -948,7 +847,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_31"> <widget class="QPushButton" name="pushButton_slot10">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -967,7 +866,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_30"> <widget class="QPushButton" name="pushButton_slot11">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -986,7 +885,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_27"> <widget class="QPushButton" name="pushButton_slot12">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -1005,7 +904,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_28"> <widget class="QPushButton" name="pushButton_slot13">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -1024,7 +923,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_25"> <widget class="QPushButton" name="pushButton_slot14">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -1043,7 +942,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_26"> <widget class="QPushButton" name="pushButton_slot15">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -1062,7 +961,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_29"> <widget class="QPushButton" name="pushButton_slot16">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -1095,6 +994,32 @@
</rect> </rect>
</property> </property>
</widget> </widget>
<widget class="QWidget" name="widget_available" native="true">
<property name="geometry">
<rect>
<x>620</x>
<y>40</y>
<width>291</width>
<height>181</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_slot_no">
<property name="geometry">
<rect>
<x>110</x>
<y>10</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>

View File

@ -2,13 +2,15 @@
#define TACHOMETERDATA_H #define TACHOMETERDATA_H
#include "cardbase.h" #include "cardbase.h"
#include <memory>
#include <vector>
class TachometerData : public CardBase { class TachometerData : public CardBase {
public: public:
TachometerData(); TachometerData();
TachometerVariables variables_[4]; TachometerVariables variables_[4];
SpeedAlert speed_alert; SpeedAlert alert_danger[CHANNEL_COUNT];
}; };
#endif // TACHOMETERDATA_H #endif // TACHOMETERDATA_H

View File

@ -1,14 +1,340 @@
#include "tmrrelayassociation.h" #include "tmrrelayassociation.h"
#include "ui_tmrrelayassociation.h" #include "ui_tmrrelayassociation.h"
#include "vibrationdata.h"
#include <QStack>
#include <QMenu>
TMRRelayAssociation::TMRRelayAssociation(QWidget *parent)
TMRRelayAssociation::TMRRelayAssociation(int slot,int cardtype,QWidget *parent)
: QDialog(parent) : QDialog(parent)
, ui(new Ui::TMRRelayAssociation) , ui(new Ui::TMRRelayAssociation)
{ {
ui->setupUi(this); ui->setupUi(this);
slot_no = slot;
car_type = static_cast<CardType>(cardtype);
ui->label_slot_no->setText(QString::number(slot_no));
QVBoxLayout *layout_available = new QVBoxLayout(ui->widget_available);
list_widget_available = new DraggableListWidget;
layout_available->addWidget(list_widget_available);
list_widget_available->setDragEnabled(true);
QVBoxLayout *layout_relay = new QVBoxLayout(ui->widget_relay);
treeView_relay = new QTreeView;
layout_relay->addWidget(treeView_relay);
treeView_relay->setDragEnabled(true); // 启用拖动
treeView_relay->setAcceptDrops(true); // 接受放下
treeView_relay->setDropIndicatorShown(true); // 显示放置指示器
treeView_relay->setDragDropMode(QAbstractItemView::DropOnly);
model_Relay = new DropTreeModel(this); //创建模型指定父类
treeView_relay->setModel(model_Relay);
treeView_relay->setHeaderHidden(true);
btnGroup_slot = new QButtonGroup(this);
btnGroup_slot->addButton(ui->pushButton_slot1);
btnGroup_slot->addButton(ui->pushButton_slot2);
btnGroup_slot->addButton(ui->pushButton_slot3);
btnGroup_slot->addButton(ui->pushButton_slot4);
btnGroup_slot->addButton(ui->pushButton_slot5);
btnGroup_slot->addButton(ui->pushButton_slot6);
btnGroup_slot->addButton(ui->pushButton_slot7);
btnGroup_slot->addButton(ui->pushButton_slot8);
btnGroup_slot->addButton(ui->pushButton_slot9);
btnGroup_slot->addButton(ui->pushButton_slot10);
btnGroup_slot->addButton(ui->pushButton_slot11);
btnGroup_slot->addButton(ui->pushButton_slot12);
btnGroup_slot->addButton(ui->pushButton_slot13);
btnGroup_slot->addButton(ui->pushButton_slot14);
btnGroup_slot->addButton(ui->pushButton_slot15);
btnGroup_slot->addButton(ui->pushButton_slot16);
connect(btnGroup_slot, SIGNAL(buttonClicked(QAbstractButton *)), this, SLOT(OnButtonGroup(QAbstractButton *)));
connect(ui->comboBox_relay_ch, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &TMRRelayAssociation::onComboBoxIndexChanged);
treeView_relay->setContextMenuPolicy(Qt::CustomContextMenu);
connect(treeView_relay,&QTreeView::customContextMenuRequested,this,&TMRRelayAssociation::on_treeView_Relay_customContextMenuRequested);
Init();
current_index = ui->comboBox_relay_ch->currentIndex();
// QString expr = "((S01C01A1 + S01C02A1 + (S02C01A1 * S02C01A2)) * (S02C01A2 + S02C01A1 + (S02C01A1 + S02C01A2)) * (S02C01A1 * S02C01A2))";
// setExpressionToTreeView(treeView_relay, expr);
} }
TMRRelayAssociation::~TMRRelayAssociation() TMRRelayAssociation::~TMRRelayAssociation()
{ {
delete ui; delete ui;
} }
void TMRRelayAssociation::Init(){
}
ExprNode* TMRRelayAssociation::parseExpression(const QString& expr, int& pos) {
auto skipSpaces = [&]() {
while (pos < expr.length() && expr[pos].isSpace()) pos++;
};
QStack<ExprNode*> nodeStack;
QStack<QString> opStack;
while (pos < expr.length()) {
skipSpaces();
if (pos >= expr.length()) break;
QChar ch = expr[pos];
if (ch == '(') {
pos++;
nodeStack.push(parseExpression(expr, pos));
} else if (ch == ')') {
pos++;
break;
} else if (ch == '+' || ch == '*') {
opStack.push(QString(ch));
pos++;
} else {
QString token;
while (pos < expr.length() && expr[pos].isLetterOrNumber()) {
token += expr[pos++];
}
nodeStack.push(new ExprNode{token, {}});
}
while (opStack.size() > 0 && nodeStack.size() >= 2) {
QString op = opStack.pop();
ExprNode* right = nodeStack.pop();
ExprNode* left = nodeStack.pop();
if (left->value == op) {
left->children.append(right);
nodeStack.push(left);
} else if (right->value == op) {
right->children.prepend(left);
nodeStack.push(right);
} else {
ExprNode* parent = new ExprNode{op, {left, right}};
nodeStack.push(parent);
}
}
}
return nodeStack.isEmpty() ? nullptr : nodeStack.top();
}
QStandardItem* TMRRelayAssociation::buildItemTree(ExprNode* node) {
if (!node) return nullptr;
QStandardItem* item = new QStandardItem(node->value);
for (ExprNode* child : node->children) {
item->appendRow(buildItemTree(child));
}
return item;
}
void TMRRelayAssociation::setExpressionToTreeView(QTreeView* treeView, const QString& expr) {
int pos = 0;
ExprNode* root = parseExpression(expr, pos);
QStandardItem* rootItem = buildItemTree(root);
QStandardItemModel* model = new QStandardItemModel();
model->appendRow(rootItem);
treeView->setModel(model);
treeView->expandAll();
}
QString TMRRelayAssociation::buildLogicExpression(QStandardItem *item) {
if (!item) return "";
int childCount = item->rowCount();
QString text = item->text().trimmed();
if (childCount == 0) {
// 叶子节点,直接返回表达式,比如 S01C01A1
return text;
}
// 判断当前是 +OR还是 *AND
QString opStr = (text == "+") ? "+" :
(text == "*") ? "*" : "";
// 如果不是 +/*,视为叶子节点
if (opStr.isEmpty()) {
return text;
}
QStringList subExprs;
for (int i = 0; i < childCount; ++i) {
QStandardItem *child = item->child(i);
subExprs << buildLogicExpression(child);
}
return "(" + subExprs.join(" " + opStr + " ") + ")";
}
QStandardItem* TMRRelayAssociation::parseExpression(const QString &expr) {
QStack<QStandardItem*> stack; // 用来存储节点
QStack<QString> ops; // 用来存储操作符
int pos = 0;
int length = expr.length();
while (pos < length) {
QRegExp regex("(\\()|([A-Za-z0-9]+)|([+*])|(\\))");
if (regex.indexIn(expr, pos) != -1) {
QString matchedText = regex.cap(0);
QString group1 = regex.cap(1); // (
QString group2 = regex.cap(2); // S01C01A1
QString group3 = regex.cap(3); // + or *
QString group4 = regex.cap(4); // )
// 处理左括号,表示子表达式的开始
if (!group1.isEmpty()) {
ops.push("("); // 推入栈
}
// 处理右括号,表示子表达式的结束
else if (!group4.isEmpty()) {
// 遇到右括号时开始弹出栈中的操作符,直到遇到左括号
while (!ops.isEmpty() && ops.top() != "(") {
QString op = ops.pop();
QStandardItem* right = stack.pop();
QStandardItem* left = stack.pop();
QStandardItem* node = new QStandardItem(op);
node->appendRow(left); // 左子树
node->appendRow(right); // 右子树
stack.push(node); // 将新的节点推入栈
}
ops.pop(); // 弹出左括号
}
// 处理操作符 + 和 *
else if (!group3.isEmpty()) {
ops.push(group3); // 操作符入栈
}
// 处理终端元素(比如 S01C01A1
else if (!group2.isEmpty()) {
QStandardItem* item = new QStandardItem(group2);
stack.push(item); // 将数据节点推入栈
}
pos = regex.pos(0) + regex.matchedLength();
} else {
break; // 防止无限循环
}
}
// 最终合并栈中的所有内容
while (!ops.isEmpty()) {
QString op = ops.pop();
QStandardItem* right = stack.pop();
QStandardItem* left = stack.pop();
QStandardItem* node = new QStandardItem(op);
node->appendRow(left); // 左子树
node->appendRow(right); // 右子树
stack.push(node);
}
// 返回栈顶的节点,应该是根节点
return stack.isEmpty() ? nullptr : stack.pop();
}
void TMRRelayAssociation::buildTreeFromExpression(QTreeView *treeView, const QString &expr) {
QStandardItemModel* model = new QStandardItemModel();
QStandardItem* rootItem = parseExpression(expr);
if (rootItem) {
model_Relay->appendRow(rootItem);
}
treeView_relay->setModel(model_Relay);
}
void TMRRelayAssociation::OnButtonGroup(QAbstractButton *slot_btn) {
if (slot_btn != NULL) {
list_widget_available->clear();
QString object_name = slot_btn->objectName();
qDebug() << object_name ;
int button_id = object_name.right(object_name.length() - 15).toInt();
std::shared_ptr<CardBase> base_ptr = ConfigMgr::Instance()->GetSlotPtr(button_id);
std::shared_ptr<VibrationData> ptr = std::dynamic_pointer_cast<VibrationData>(base_ptr);
for(int var = 0; var < CHANNEL_COUNT ; ++var){
if(ptr->alert_danger[var].direct_enable ||
ptr->alert_danger[var].x1_ampl_enable ||
ptr->alert_danger[var].x2_ampl_enable){
QString item_str = QString("S%1C%2A1 (槽位 %3 通道 %4 警报)").arg(QString::number(button_id, 10).rightJustified(2, '0')).arg(QString::number(var+1, 10).rightJustified(2, '0')).arg(button_id).arg(var+1);
QListWidgetItem *item = new QListWidgetItem(item_str);
QString item_data = QString("S%1C%2A1").arg(QString::number(button_id, 10).rightJustified(2, '0')).arg(QString::number(var+1, 10).rightJustified(2, '0'));
item->setData(Qt::UserRole, item_data);
list_widget_available->addItem(item);
}
if(ptr->alert_danger[var].danger_enable){
QString item_str = QString("S%1C%2A2 (槽位 %3 通道 %4 危险)").arg(QString::number(button_id, 10).rightJustified(2, '0')).arg(QString::number(var+1, 10).rightJustified(2, '0')).arg(button_id).arg(var+1);
QListWidgetItem *item = new QListWidgetItem(item_str);
QString item_data = QString("S%1C%2A2").arg(QString::number(button_id, 10).rightJustified(2, '0')).arg(QString::number(var+1, 10).rightJustified(2, '0'));
item->setData(Qt::UserRole, item_data);
list_widget_available->addItem(item);
}
}
QString item_str = QString("*");
QListWidgetItem *item_or = new QListWidgetItem("*");
item_or->setData(Qt::UserRole, "*");
list_widget_available->addItem(item_or);
QListWidgetItem *item_and = new QListWidgetItem("+");
item_and->setData(Qt::UserRole, "+");
list_widget_available->addItem(item_and);
}
}
void TMRRelayAssociation::on_pushButton_cancel_clicked()
{
this->close();
}
void TMRRelayAssociation::on_pushButton_confirm_clicked()
{
QStandardItemModel *model = qobject_cast<QStandardItemModel *>(treeView_relay->model());
if (!model) return;
QStandardItem *root = model->invisibleRootItem();
QString finalExpr;
for (int i = 0; i < root->rowCount(); ++i) {
QStandardItem *topItem = root->child(i);
QString expr = buildLogicExpression(topItem);
if (!finalExpr.isEmpty()) {
finalExpr += " OR ";
}
finalExpr += expr;
}
qDebug() << "逻辑表达式:" << finalExpr;
this->close();
}
void TMRRelayAssociation::onComboBoxIndexChanged(int index){
}
void TMRRelayAssociation::on_pushButton_and_clicked()
{
}
void TMRRelayAssociation::on_pushButton_or_clicked()
{
}
void TMRRelayAssociation::slotDeleteItem()
{
QModelIndex curIndex = treeView_relay->currentIndex();
if(curIndex.isValid()){
model_Relay->removeRow(curIndex.row(),curIndex.parent());
}
}
void TMRRelayAssociation::on_treeView_Relay_customContextMenuRequested(const QPoint &pos)
{
qDebug() << "on_treeView_Relay_customContextMenuRequested" <<endl;
QModelIndex curIndex = treeView_relay->indexAt(pos); //当前点击的元素的index
QModelIndex index = curIndex.sibling(curIndex.row(),0); //该行的第1列元素的index
QMenu menu(this);
if (index.isValid()){
//添加一行菜单,进行展开
menu.addAction(QStringLiteral("删除"), this, SLOT(slotDeleteItem()));
menu.addSeparator(); //添加一个分隔线
}
menu.exec(QCursor::pos()); //显示菜单
}

View File

@ -2,21 +2,97 @@
#define TMRRELAYASSOCIATION_H #define TMRRELAYASSOCIATION_H
#include <QDialog> #include <QDialog>
#include <QButtonGroup>
#include <QPushButton>
#include "data_config.h"
#include "config_mgr.h"
#include <QStandardItemModel> //数据模型类
#include <QTreeView>
namespace Ui { namespace Ui {
class TMRRelayAssociation; class TMRRelayAssociation;
} }
struct ExprNode {
QString value;
QList<ExprNode*> children;
};
class DropTreeModel : public QStandardItemModel {
public:
using QStandardItemModel::QStandardItemModel;
QStringList mimeTypes() const override {
return { "application/x-custom" };
}
bool dropMimeData(const QMimeData *data, Qt::DropAction action,
int row, int column, const QModelIndex &parent) override {
if (!data->hasFormat("application/x-custom"))
return false;
QByteArray rawData = data->data("application/x-custom");
QString customText = QString::fromUtf8(rawData);
QStandardItem *newItem = new QStandardItem(customText);
newItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable |
Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
QStandardItem *parentItem = this->itemFromIndex(parent);
if (!parentItem) parentItem = this->invisibleRootItem();
if (row < 0)
parentItem->appendRow(newItem);
else
parentItem->insertRow(row, newItem);
return true;
}
Qt::DropActions supportedDropActions() const override {
return Qt::CopyAction;
}
};
class TMRRelayAssociation : public QDialog class TMRRelayAssociation : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit TMRRelayAssociation(QWidget *parent = nullptr); explicit TMRRelayAssociation(int slot,int cardtype,QWidget *parent = nullptr);
~TMRRelayAssociation(); ~TMRRelayAssociation();
int slot_no;
CardType car_type;
private slots:
void on_pushButton_cancel_clicked();
void on_pushButton_confirm_clicked();
void onComboBoxIndexChanged(int index);
void OnButtonGroup(QAbstractButton *);
void on_pushButton_and_clicked();
void on_pushButton_or_clicked();
void on_treeView_Relay_customContextMenuRequested(const QPoint &pos);
void slotDeleteItem();
private: private:
Ui::TMRRelayAssociation *ui; Ui::TMRRelayAssociation *ui;
QButtonGroup * btnGroup_slot = nullptr;
DraggableListWidget *list_widget_available = nullptr;
int current_index;
QTreeView *treeView_relay;
QStandardItemModel *model_Relay;
void Init();
void buildTreeFromExpression(QTreeView *treeView, const QString &expr);
ExprNode* parseExpression(const QString& expr, int& pos);
QStandardItem* buildItemTree(ExprNode* node);
void setExpressionToTreeView(QTreeView* treeView, const QString& expr);
QStandardItem* parseExpression(const QString &expr);
QString buildLogicExpression(QStandardItem *item);
}; };
#endif // TMRRELAYASSOCIATION_H #endif // TMRRELAYASSOCIATION_H

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>853</width> <width>869</width>
<height>624</height> <height>624</height>
</rect> </rect>
</property> </property>
@ -26,19 +26,6 @@
<string>继电器槽位:</string> <string>继电器槽位:</string>
</property> </property>
</widget> </widget>
<widget class="QLineEdit" name="lineEdit">
<property name="geometry">
<rect>
<x>123</x>
<y>19</y>
<width>31</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string> 13</string>
</property>
</widget>
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="geometry"> <property name="geometry">
<rect> <rect>
@ -52,56 +39,6 @@
<string>可用的告警:</string> <string>可用的告警:</string>
</property> </property>
</widget> </widget>
<widget class="QListWidget" name="listWidget">
<property name="geometry">
<rect>
<x>230</x>
<y>360</y>
<width>361</width>
<height>161</height>
</rect>
</property>
<item>
<property name="text">
<string>S02C01A1 (Slot 2 Channel 1 Alert)</string>
</property>
</item>
<item>
<property name="text">
<string>S02C01A2 (Slot 2 Channel 1 Danger)</string>
</property>
</item>
<item>
<property name="text">
<string>S02C02A1 (Slot 2 Channel 2 Alert)</string>
</property>
</item>
<item>
<property name="text">
<string>S02C02A2 (Slot 2 Channel 2 Danger)</string>
</property>
</item>
<item>
<property name="text">
<string>S02C03A1 (Slot 2 Channel 3 Alert)</string>
</property>
</item>
<item>
<property name="text">
<string>S02C03A2 (Slot 2 Channel 3 Danger)</string>
</property>
</item>
<item>
<property name="text">
<string>S02C04A1 (Slot 2 Channel 4 Alert)</string>
</property>
</item>
<item>
<property name="text">
<string>S02C04A2 (Slot 2 Channel 4 Danger)</string>
</property>
</item>
</widget>
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="groupBox_2">
<property name="geometry"> <property name="geometry">
<rect> <rect>
@ -114,7 +51,7 @@
<property name="title"> <property name="title">
<string>TMR继电器关联</string> <string>TMR继电器关联</string>
</property> </property>
<widget class="QComboBox" name="comboBox"> <widget class="QComboBox" name="comboBox_relay_ch">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>20</x> <x>20</x>
@ -234,8 +171,8 @@
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>60</x> <x>620</x>
<y>550</y> <y>60</y>
<width>91</width> <width>91</width>
<height>16</height> <height>16</height>
</rect> </rect>
@ -270,10 +207,10 @@
<string>打 印...</string> <string>打 印...</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="pushButton_10"> <widget class="QPushButton" name="pushButton_confirm">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>230</x> <x>240</x>
<y>590</y> <y>590</y>
<width>71</width> <width>71</width>
<height>32</height> <height>32</height>
@ -302,7 +239,7 @@
<widget class="QPushButton" name="pushButton_cancel"> <widget class="QPushButton" name="pushButton_cancel">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>410</x> <x>350</x>
<y>590</y> <y>590</y>
<width>71</width> <width>71</width>
<height>32</height> <height>32</height>
@ -325,7 +262,7 @@
<string>NCT6100T</string> <string>NCT6100T</string>
</property> </property>
</widget> </widget>
<widget class="QCheckBox" name="checkBox_3"> <widget class="QCheckBox" name="checkBox_guowang">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>30</x> <x>30</x>
@ -710,7 +647,7 @@
<widget class="QWidget" name="widget_3" native="true"> <widget class="QWidget" name="widget_3" native="true">
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QPushButton" name="pushButton_17"> <widget class="QPushButton" name="pushButton_slot1">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -729,7 +666,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_18"> <widget class="QPushButton" name="pushButton_slot2">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -748,7 +685,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_20"> <widget class="QPushButton" name="pushButton_slot3">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -767,7 +704,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_19"> <widget class="QPushButton" name="pushButton_slot4">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -786,7 +723,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_24"> <widget class="QPushButton" name="pushButton_slot5">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -805,7 +742,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_23"> <widget class="QPushButton" name="pushButton_slot6">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -824,7 +761,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_22"> <widget class="QPushButton" name="pushButton_slot7">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -843,7 +780,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_21"> <widget class="QPushButton" name="pushButton_slot8">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -862,7 +799,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_32"> <widget class="QPushButton" name="pushButton_slot9">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -881,7 +818,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_31"> <widget class="QPushButton" name="pushButton_slot10">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -900,7 +837,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_30"> <widget class="QPushButton" name="pushButton_slot11">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -919,7 +856,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_27"> <widget class="QPushButton" name="pushButton_slot12">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -938,7 +875,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_28"> <widget class="QPushButton" name="pushButton_slot13">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -957,7 +894,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_25"> <widget class="QPushButton" name="pushButton_slot14">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -976,7 +913,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_26"> <widget class="QPushButton" name="pushButton_slot15">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -995,7 +932,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="pushButton_29"> <widget class="QPushButton" name="pushButton_slot16">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>30</width> <width>30</width>
@ -1018,13 +955,62 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QTreeView" name="treeView"> <widget class="QLabel" name="label_slot_no">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>620</x> <x>130</x>
<y>90</y> <y>20</y>
<width>201</width> <width>54</width>
<height>431</height> <height>12</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_and">
<property name="geometry">
<rect>
<x>540</x>
<y>380</y>
<width>51</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>与(+)</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_or">
<property name="geometry">
<rect>
<x>540</x>
<y>440</y>
<width>51</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>或(*)</string>
</property>
</widget>
<widget class="QWidget" name="widget_available" native="true">
<property name="geometry">
<rect>
<x>230</x>
<y>360</y>
<width>301</width>
<height>161</height>
</rect>
</property>
</widget>
<widget class="QWidget" name="widget_relay" native="true">
<property name="geometry">
<rect>
<x>610</x>
<y>80</y>
<width>191</width>
<height>421</height>
</rect> </rect>
</property> </property>
</widget> </widget>

View File

@ -12,7 +12,7 @@ class VibrationData : public CardBase {
void RemoveChannel(int cid); void RemoveChannel(int cid);
SeismicMonitor base_config_[CHANNEL_COUNT]; SeismicMonitor base_config_[CHANNEL_COUNT];
std::vector<std::shared_ptr<VariableBase>> variables_; std::vector<std::shared_ptr<VariableBase>> variables_;
VibAlertDanger vib_alert_danger[CHANNEL_COUNT]; VibAlertDanger alert_danger[CHANNEL_COUNT];
}; };
#endif // VIBRATIONDATA_H #endif // VIBRATIONDATA_H