@@ -11,6 +11,11 @@ void Coil::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid | |||||
{ | { | ||||
painter->setRenderHint(QPainter::Antialiasing); | painter->setRenderHint(QPainter::Antialiasing); | ||||
if (registerValue_ > 0) { | |||||
painter->setBrush(Qt::green); // 激活状态 | |||||
} else { | |||||
painter->setBrush(Qt::black); // 未激活状态 | |||||
} | |||||
if (type_ == "线圈") { | if (type_ == "线圈") { | ||||
// 绘制线圈样式: 两边线段+中间椭圆 | // 绘制线圈样式: 两边线段+中间椭圆 | ||||
painter->drawLine(-12, 0, -5, 0); | painter->drawLine(-12, 0, -5, 0); | ||||
@@ -28,8 +33,10 @@ void Coil::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid | |||||
painter->setFont(QFont("Arial", 8)); | painter->setFont(QFont("Arial", 8)); | ||||
painter->setPen(Qt::black); | painter->setPen(Qt::black); | ||||
// 在元件底部居中绘制寄存器ID | // 在元件底部居中绘制寄存器ID | ||||
painter->drawText(boundingRect().adjusted(0, 20, 0, 0), | |||||
Qt::AlignCenter, registerId_); | |||||
// painter->drawText(boundingRect().adjusted(0, 20, 0, 0), | |||||
// Qt::AlignCenter, registerId_); | |||||
QString text = QString("%1: %2").arg(registerId()).arg(registerValue_); | |||||
painter->drawText(boundingRect(), Qt::AlignBottom | Qt::AlignHCenter, text); | |||||
painter->restore(); | painter->restore(); | ||||
} | } | ||||
if (option->state & QStyle::State_Selected) { | if (option->state & QStyle::State_Selected) { | ||||
@@ -41,3 +48,8 @@ void Coil::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid | |||||
painter->drawRect(boundingRect()); | painter->drawRect(boundingRect()); | ||||
} | } | ||||
} | } | ||||
bool Coil::state() const | |||||
{ | |||||
return registerValue_ > 0; | |||||
} |
@@ -9,6 +9,7 @@ public: | |||||
void paint(QPainter *painter, | void paint(QPainter *painter, | ||||
const QStyleOptionGraphicsItem *option, | const QStyleOptionGraphicsItem *option, | ||||
QWidget *) override; | QWidget *) override; | ||||
bool state() const override; | |||||
}; | }; | ||||
#endif // COIL_H | #endif // COIL_H |
@@ -11,6 +11,11 @@ void Contact::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q | |||||
{ | { | ||||
painter->setRenderHint(QPainter::Antialiasing); | painter->setRenderHint(QPainter::Antialiasing); | ||||
if (type_ == "常开") { | if (type_ == "常开") { | ||||
if (state()) { | |||||
painter->setPen(QPen(Qt::green, 2)); // 激活状态 | |||||
} else { | |||||
painter->setPen(QPen(Qt::black, 1)); // 未激活状态 | |||||
} | |||||
painter->drawLine(-12, 0, -4, 0); | painter->drawLine(-12, 0, -4, 0); | ||||
painter->drawLine(-4, -8, -4, 8); | painter->drawLine(-4, -8, -4, 8); | ||||
painter->drawLine(4, -8, 4, 8); | painter->drawLine(4, -8, 4, 8); | ||||
@@ -23,6 +28,11 @@ void Contact::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q | |||||
painter->drawEllipse(QPointF(18, 0), 4, 4); // 右 | painter->drawEllipse(QPointF(18, 0), 4, 4); // 右 | ||||
} | } | ||||
else if (type_ == "常闭") { | else if (type_ == "常闭") { | ||||
if (!state()) { | |||||
painter->setPen(QPen(Qt::green, 2)); // 激活状态 | |||||
} else { | |||||
painter->setPen(QPen(Qt::black, 1)); // 未激活状态 | |||||
} | |||||
painter->drawLine(-15, -10, 15, 10); // 对角线 | painter->drawLine(-15, -10, 15, 10); // 对角线 | ||||
painter->drawLine(-12, 0, -4, 0); | painter->drawLine(-12, 0, -4, 0); | ||||
painter->drawLine(-4, -8, -4, 8); | painter->drawLine(-4, -8, -4, 8); | ||||
@@ -41,8 +51,8 @@ void Contact::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q | |||||
painter->setFont(QFont("Arial", 8)); | painter->setFont(QFont("Arial", 8)); | ||||
painter->setPen(Qt::black); | painter->setPen(Qt::black); | ||||
// 在元件底部居中绘制寄存器ID | // 在元件底部居中绘制寄存器ID | ||||
painter->drawText(boundingRect().adjusted(0, 20, 0, 0), | |||||
Qt::AlignCenter, registerId_); | |||||
QString text = QString("%1: %2").arg(registerId()).arg(registerValue_); | |||||
painter->drawText(boundingRect(), Qt::AlignBottom | Qt::AlignHCenter, text); | |||||
painter->restore(); | painter->restore(); | ||||
} | } | ||||
if (option->state & QStyle::State_Selected) { | if (option->state & QStyle::State_Selected) { | ||||
@@ -54,3 +64,8 @@ void Contact::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q | |||||
painter->drawRect(boundingRect()); | painter->drawRect(boundingRect()); | ||||
} | } | ||||
} | } | ||||
bool Contact::state() const | |||||
{ | |||||
return registerValue_ > 0; | |||||
} |
@@ -9,6 +9,7 @@ public: | |||||
void paint(QPainter *painter, | void paint(QPainter *painter, | ||||
const QStyleOptionGraphicsItem *option, | const QStyleOptionGraphicsItem *option, | ||||
QWidget *) override; | QWidget *) override; | ||||
bool state() const override; | |||||
}; | }; | ||||
#endif // CONTACT_H | #endif // CONTACT_H |
@@ -1,4 +1,6 @@ | |||||
QT += core gui | QT += core gui | ||||
QT += serialport | |||||
QT += serialbus | |||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets | ||||
@@ -27,9 +29,11 @@ SOURCES += \ | |||||
light.cpp \ | light.cpp \ | ||||
main.cpp \ | main.cpp \ | ||||
mainwindow.cpp \ | mainwindow.cpp \ | ||||
modbusmanager.cpp \ | |||||
mygraphicsview.cpp \ | mygraphicsview.cpp \ | ||||
plc.cpp \ | plc.cpp \ | ||||
project.cpp | |||||
project.cpp \ | |||||
registermanager.cpp | |||||
HEADERS += \ | HEADERS += \ | ||||
button.h \ | button.h \ | ||||
@@ -42,9 +46,11 @@ HEADERS += \ | |||||
item.h \ | item.h \ | ||||
light.h \ | light.h \ | ||||
mainwindow.h \ | mainwindow.h \ | ||||
modbusmanager.h \ | |||||
mygraphicsview.h \ | mygraphicsview.h \ | ||||
plc.h \ | plc.h \ | ||||
project.h | |||||
project.h \ | |||||
registermanager.h | |||||
FORMS += \ | FORMS += \ | ||||
hmi.ui \ | hmi.ui \ | ||||
@@ -58,6 +58,12 @@ QString Item::itemType() | |||||
return type_; | return type_; | ||||
} | } | ||||
void Item::setRegisterValue(quint16 value) | |||||
{ | |||||
registerValue_ = value; | |||||
update(); // 触发重绘 | |||||
} | |||||
void Item::MenuActions(QMenu *menu) | void Item::MenuActions(QMenu *menu) | ||||
{ | { | ||||
menu->addAction("复制"); | menu->addAction("复制"); | ||||
@@ -23,6 +23,11 @@ public: | |||||
QString itemType(); | QString itemType(); | ||||
void setRegisterId(const QString& id) { registerId_ = id; } | void setRegisterId(const QString& id) { registerId_ = id; } | ||||
QString registerId() const { return registerId_; } | QString registerId() const { return registerId_; } | ||||
void setRegisterValue(quint16 value); | |||||
quint16 registerValue() const { return registerValue_; } | |||||
// 添加状态属性(用于线圈、触点等) | |||||
virtual bool state() const { return false; } | |||||
signals: | signals: | ||||
@@ -39,6 +44,7 @@ protected: | |||||
QString type_; | QString type_; | ||||
QList<Connection*> connections_; | QList<Connection*> connections_; | ||||
QString registerId_; | QString registerId_; | ||||
quint16 registerValue_ = 0; | |||||
}; | }; | ||||
#endif // ITEM_H | #endif // ITEM_H |
@@ -30,6 +30,7 @@ MainWindow::MainWindow(QWidget *parent) | |||||
connect(ui->action_save, &QAction::triggered, this, &MainWindow::saveProject); | connect(ui->action_save, &QAction::triggered, this, &MainWindow::saveProject); | ||||
connect(ui->action_open, &QAction::triggered, this, &MainWindow::openProject); | connect(ui->action_open, &QAction::triggered, this, &MainWindow::openProject); | ||||
plc_->applyProjectToScene(plcProject_); // 初始空 | plc_->applyProjectToScene(plcProject_); // 初始空 | ||||
hmi_->applyProjectToScene(hmiProject_); | hmi_->applyProjectToScene(hmiProject_); | ||||
} | } | ||||
@@ -2,8 +2,10 @@ | |||||
#define MAINWINDOW_H | #define MAINWINDOW_H | ||||
#include <QMainWindow> | #include <QMainWindow> | ||||
#include <plc.h> | |||||
#include <hmi.h> | |||||
#include "plc.h" | |||||
#include "hmi.h" | |||||
#include "modbusmanager.h" | |||||
#include "registermanager.h" | |||||
QT_BEGIN_NAMESPACE | QT_BEGIN_NAMESPACE | ||||
namespace Ui { class MainWindow; } | namespace Ui { class MainWindow; } | ||||
@@ -0,0 +1,146 @@ | |||||
#include "modbusmanager.h" | |||||
#include <QModbusDataUnit> | |||||
#include <QDebug> | |||||
ModbusManager::ModbusManager(RegisterManager* regManager, QObject *parent) | |||||
: QObject(parent), registerManager(regManager) | |||||
{ | |||||
modbusDevice = new QModbusRtuSerialMaster(this); | |||||
pollTimer = new QTimer(this); | |||||
connect(modbusDevice, &QModbusClient::errorOccurred, this, | |||||
[this](QModbusDevice::Error) { | |||||
emit errorOccurred(modbusDevice->errorString()); | |||||
}); | |||||
connect(pollTimer, &QTimer::timeout, this, &ModbusManager::readRegisters); | |||||
} | |||||
ModbusManager::~ModbusManager() | |||||
{ | |||||
stopSimulation(); | |||||
disconnectDevice(); | |||||
} | |||||
bool ModbusManager::connectToDevice(const QString& portName, | |||||
QSerialPort::BaudRate baudRate, | |||||
QSerialPort::DataBits dataBits, | |||||
QSerialPort::Parity parity, | |||||
QSerialPort::StopBits stopBits) | |||||
{ | |||||
if (modbusDevice->state() != QModbusDevice::UnconnectedState) { | |||||
disconnectDevice(); | |||||
} | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, portName); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, baudRate); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, dataBits); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, parity); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, stopBits); | |||||
if (!modbusDevice->connectDevice()) { | |||||
emit errorOccurred(tr("连接失败: %1").arg(modbusDevice->errorString())); | |||||
return false; | |||||
} | |||||
emit connectionStatusChanged(true); | |||||
return true; | |||||
} | |||||
void ModbusManager::disconnectDevice() | |||||
{ | |||||
if (modbusDevice->state() != QModbusDevice::UnconnectedState) { | |||||
modbusDevice->disconnectDevice(); | |||||
emit connectionStatusChanged(false); | |||||
} | |||||
} | |||||
void ModbusManager::startSimulation(int interval) | |||||
{ | |||||
pollTimer->start(interval); | |||||
} | |||||
void ModbusManager::stopSimulation() | |||||
{ | |||||
pollTimer->stop(); | |||||
} | |||||
void ModbusManager::readRegisters() | |||||
{ | |||||
if (!modbusDevice || modbusDevice->state() != QModbusDevice::ConnectedState) | |||||
return; | |||||
// 读取所有D寄存器 (保持寄存器) | |||||
readRegisterGroup(QModbusDataUnit::HoldingRegisters, 0, 4000); | |||||
// 读取所有M寄存器 (线圈) | |||||
readRegisterGroup(QModbusDataUnit::Coils, 0, 4000); | |||||
} | |||||
void ModbusManager::readRegisterGroup(QModbusDataUnit::RegisterType type, int startAddr, int count) | |||||
{ | |||||
const int MAX_REG_PER_REQUEST = 125; // Modbus RTU限制 | |||||
for (int addr = startAddr; addr < count; addr += MAX_REG_PER_REQUEST) { | |||||
int readCount = qMin(MAX_REG_PER_REQUEST, count - addr); | |||||
QModbusDataUnit unit(type, addr, readCount); | |||||
if (auto *reply = modbusDevice->sendReadRequest(unit, slaveAddress)) { | |||||
QString regType = (type == QModbusDataUnit::HoldingRegisters) ? "D" : "M"; | |||||
pendingRequests[reply] = regType; | |||||
connect(reply, &QModbusReply::finished, this, &ModbusManager::processModbusReply); | |||||
} | |||||
} | |||||
} | |||||
void ModbusManager::processModbusReply() | |||||
{ | |||||
auto *reply = qobject_cast<QModbusReply*>(sender()); | |||||
if (!reply) return; | |||||
if (reply->error() == QModbusDevice::NoError) { | |||||
const QModbusDataUnit unit = reply->result(); | |||||
QString regType = pendingRequests.value(reply); | |||||
int startAddr = unit.startAddress(); | |||||
for (uint i = 0; i < unit.valueCount(); i++) { | |||||
int regAddr = startAddr + i; | |||||
quint16 value = unit.value(i); | |||||
QString regId = QString("%1%2").arg(regType).arg(regAddr); | |||||
// 更新图元状态 | |||||
registerManager->updateRegisterValue(regId, value); | |||||
} | |||||
} else { | |||||
emit errorOccurred(tr("Modbus错误: %1").arg(reply->errorString())); | |||||
} | |||||
pendingRequests.remove(reply); | |||||
reply->deleteLater(); | |||||
} | |||||
void ModbusManager::writeRegister(const QString& registerId, quint16 value) | |||||
{ | |||||
if (registerId.isEmpty()) return; | |||||
QModbusDataUnit::RegisterType regType = registerId.startsWith("D") | |||||
? QModbusDataUnit::HoldingRegisters | |||||
: QModbusDataUnit::Coils; | |||||
int regAddr = registerId.mid(1).toInt(); | |||||
QModbusDataUnit writeUnit(regType, regAddr, 1); | |||||
writeUnit.setValue(0, value); | |||||
if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, slaveAddress)) { | |||||
connect(reply, &QModbusReply::finished, this, [this, reply]() { | |||||
if (reply->error() != QModbusDevice::NoError) { | |||||
emit errorOccurred(tr("写入失败: %1").arg(reply->errorString())); | |||||
} | |||||
reply->deleteLater(); | |||||
}); | |||||
} | |||||
} |
@@ -0,0 +1,55 @@ | |||||
#ifndef MODBUSMANAGER_H | |||||
#define MODBUSMANAGER_H | |||||
#include <QObject> | |||||
#include <QModbusRtuSerialMaster> | |||||
#include <QSerialPort> | |||||
#include <QTimer> | |||||
#include <QMap> | |||||
#include "registermanager.h" | |||||
class ModbusManager : public QObject | |||||
{ | |||||
Q_OBJECT | |||||
public: | |||||
explicit ModbusManager(RegisterManager* regManager, QObject *parent = nullptr); | |||||
~ModbusManager(); | |||||
// 串口连接管理 | |||||
bool connectToDevice(const QString& portName, | |||||
QSerialPort::BaudRate baudRate = QSerialPort::Baud9600, | |||||
QSerialPort::DataBits dataBits = QSerialPort::Data8, | |||||
QSerialPort::Parity parity = QSerialPort::NoParity, | |||||
QSerialPort::StopBits stopBits = QSerialPort::OneStop); | |||||
void disconnectDevice(); | |||||
// 仿真控制 | |||||
void startSimulation(int interval = 500); // 毫秒 | |||||
void stopSimulation(); | |||||
// 寄存器读写 | |||||
void writeRegister(const QString& registerId, quint16 value); | |||||
// 设置从站地址 | |||||
void setSlaveAddress(int address) { slaveAddress = address; } | |||||
signals: | |||||
void connectionStatusChanged(bool connected); | |||||
void errorOccurred(const QString& error); | |||||
private slots: | |||||
void readRegisters(); | |||||
void processModbusReply(); | |||||
private: | |||||
QModbusRtuSerialMaster *modbusDevice; | |||||
RegisterManager* registerManager; | |||||
QTimer* pollTimer; | |||||
int slaveAddress = 1; // 默认从站地址 | |||||
QMap<QModbusReply*, QString> pendingRequests; | |||||
void readRegisterGroup(QModbusDataUnit::RegisterType type, int startAddr, int count); | |||||
}; | |||||
#endif // MODBUSMANAGER_H |
@@ -5,6 +5,8 @@ | |||||
#include <QDebug> | #include <QDebug> | ||||
#include <QMenu> | #include <QMenu> | ||||
#include <QInputDialog> | #include <QInputDialog> | ||||
#include <QMessageBox> | |||||
#include <QRegularExpression> | |||||
MyGraphicsView::ClipInfo MyGraphicsView::clipboard_ = {}; | MyGraphicsView::ClipInfo MyGraphicsView::clipboard_ = {}; | ||||
@@ -165,16 +167,45 @@ void MyGraphicsView::onItemRequestDelete(Item *item) | |||||
void MyGraphicsView::onItemRequestBindRegister(Item *item) | void MyGraphicsView::onItemRequestBindRegister(Item *item) | ||||
{ | { | ||||
if (!item) return; | |||||
bool ok = false; | bool ok = false; | ||||
QString reg = QInputDialog::getText(this, | |||||
"寄存器", | |||||
"编号:", | |||||
QLineEdit::Normal, | |||||
item->registerId(), | |||||
&ok); | |||||
QString reg = QInputDialog::getText( | |||||
this, | |||||
"绑定寄存器", | |||||
"格式: <类型><地址>\n" | |||||
"类型: D(保持寄存器), M(线圈寄存器)\n" | |||||
"示例: D100, M200\n" | |||||
"地址范围: 0-4000", | |||||
QLineEdit::Normal, | |||||
item->registerId(), | |||||
&ok | |||||
); | |||||
if (ok && !reg.isEmpty()) { | if (ok && !reg.isEmpty()) { | ||||
item->setRegisterId(reg); | |||||
// 验证寄存器格式 | |||||
QRegularExpression regex("^[DMdm]\\d{1,4}$"); | |||||
QRegularExpressionMatch match = regex.match(reg); | |||||
if (!match.hasMatch()) { | |||||
QMessageBox::warning(this, "格式错误", "请输入有效的寄存器格式\n示例: D100, M200"); | |||||
return; | |||||
} | |||||
int address = reg.mid(1).toInt(); | |||||
if (address > 4000) { | |||||
QMessageBox::warning(this, "范围错误", "寄存器地址必须在0-4000范围内"); | |||||
return; | |||||
} | |||||
// 标准化格式 (D100) | |||||
QString newReg = QString("%1%2").arg(reg[0].toUpper()).arg(address); | |||||
item->setRegisterId(newReg); | |||||
item->update(); | item->update(); | ||||
// 发出绑定信号 | |||||
emit itemBoundToRegister(item, newReg); | |||||
} | } | ||||
} | } | ||||
@@ -28,6 +28,9 @@ protected: | |||||
void mouseMoveEvent(QMouseEvent *event) override; | void mouseMoveEvent(QMouseEvent *event) override; | ||||
void mouseReleaseEvent(QMouseEvent *event) override; | void mouseReleaseEvent(QMouseEvent *event) override; | ||||
signals: | |||||
void itemBoundToRegister(Item*, QString); | |||||
private: | private: | ||||
Item* anchorItemAt(const QPoint& viewPos, Item::AnchorType& anchorType); | Item* anchorItemAt(const QPoint& viewPos, Item::AnchorType& anchorType); | ||||
@@ -17,6 +17,8 @@ PLC::PLC(QWidget *parent) : | |||||
ui(new Ui::PLC) | ui(new Ui::PLC) | ||||
{ | { | ||||
ui->setupUi(this); | ui->setupUi(this); | ||||
registerManager = new RegisterManager(this); | |||||
modbusManager = new ModbusManager(registerManager, this); | |||||
/* 1. 场景 */ | /* 1. 场景 */ | ||||
plc_scene_ = new QGraphicsScene(this); | plc_scene_ = new QGraphicsScene(this); | ||||
ui->graphicsView->setScene(plc_scene_); | ui->graphicsView->setScene(plc_scene_); | ||||
@@ -33,6 +35,14 @@ PLC::PLC(QWidget *parent) : | |||||
createComponents(); | createComponents(); | ||||
connect(ui->listWidget,&QListWidget::currentTextChanged,this,&PLC::onListwidgetCurrenttextchanged); | connect(ui->listWidget,&QListWidget::currentTextChanged,this,&PLC::onListwidgetCurrenttextchanged); | ||||
connect(ui->btn_insert,&QPushButton::clicked,this,&PLC::btnInsertClicked); | connect(ui->btn_insert,&QPushButton::clicked,this,&PLC::btnInsertClicked); | ||||
// connect(modbusManager, &ModbusManager::connectionStatusChanged, | |||||
// this, &PLC::updateConnectionStatus); | |||||
// connect(modbusManager, &ModbusManager::errorOccurred, | |||||
// this, &PLC::handleModbusError); | |||||
connect(ui->graphicsView, &MyGraphicsView::itemBoundToRegister, | |||||
registerManager, &RegisterManager::bindItem); | |||||
// connect(this, &PLC::requestWriteRegister, | |||||
// modbusManager, &ModbusManager::writeRegister); | |||||
} | } | ||||
PLC::~PLC() | PLC::~PLC() | ||||
@@ -3,6 +3,7 @@ | |||||
#include <QGraphicsScene> | #include <QGraphicsScene> | ||||
#include <QWidget> | #include <QWidget> | ||||
#include "modbusmanager.h" | |||||
#include "project.h" | #include "project.h" | ||||
namespace Ui { | namespace Ui { | ||||
@@ -32,6 +33,8 @@ private slots: | |||||
private: | private: | ||||
Ui::PLC *ui; | Ui::PLC *ui; | ||||
QGraphicsScene *plc_scene_; | QGraphicsScene *plc_scene_; | ||||
ModbusManager* modbusManager; | |||||
RegisterManager* registerManager; | |||||
QString selectedComponentType; | QString selectedComponentType; | ||||
}; | }; | ||||
@@ -0,0 +1,44 @@ | |||||
// registermanager.cpp | |||||
#include "registermanager.h" | |||||
#include "item.h" | |||||
RegisterManager::RegisterManager(QObject *parent) : QObject(parent) {} | |||||
void RegisterManager::bindItem(Item* item, const QString& registerId) | |||||
{ | |||||
if (registerId.isEmpty() || !item) return; | |||||
// 添加到映射表 | |||||
registerMap[registerId].append(item); | |||||
// 连接图元销毁信号 | |||||
connect(item, &Item::destroyed, this, [this, item, registerId](){ | |||||
if (registerMap.contains(registerId)) { | |||||
registerMap[registerId].removeAll(item); | |||||
if (registerMap[registerId].isEmpty()) { | |||||
registerMap.remove(registerId); | |||||
} | |||||
} | |||||
}); | |||||
} | |||||
void RegisterManager::updateRegisterValue(const QString& registerId, quint16 value) | |||||
{ | |||||
if (!registerMap.contains(registerId)) return; | |||||
// 更新所有绑定该寄存器的图元 | |||||
for (Item* item : registerMap[registerId]) { | |||||
item->setRegisterValue(value); | |||||
item->update(); // 刷新显示 | |||||
} | |||||
} | |||||
QStringList RegisterManager::getAllRegisteredRegisters() const | |||||
{ | |||||
return registerMap.keys(); | |||||
} | |||||
QList<Item*> RegisterManager::getItemsForRegister(const QString& registerId) const | |||||
{ | |||||
return registerMap.value(registerId, QList<Item*>()); | |||||
} |
@@ -0,0 +1,28 @@ | |||||
#ifndef REGISTERMANAGER_H | |||||
#define REGISTERMANAGER_H | |||||
#include <QObject> | |||||
#include "item.h" | |||||
class RegisterManager : public QObject | |||||
{ | |||||
Q_OBJECT | |||||
public: | |||||
explicit RegisterManager(QObject *parent = nullptr); | |||||
// 注册图元与寄存器绑定关系 | |||||
void bindItem(Item* item, const QString& registerId); | |||||
// 更新寄存器值 | |||||
void updateRegisterValue(const QString& registerId, quint16 value); | |||||
QStringList getAllRegisteredRegisters() const; | |||||
// 获取绑定特定寄存器的所有图元 | |||||
QList<Item*> getItemsForRegister(const QString& registerId) const; | |||||
private: | |||||
// 寄存器到图元的映射 (寄存器ID -> 图元列表) | |||||
QMap<QString, QList<Item*>> registerMap; | |||||
}; | |||||
#endif // REGISTERMANAGER_H |