@@ -56,16 +56,19 @@ void Comparator::paint(QPainter *painter, const QStyleOptionGraphicsItem *option | |||
} | |||
} | |||
void Comparator::setRegisterId(const QString &id) | |||
bool Comparator::setRegisterId(const QString &id) | |||
{ | |||
if (registerId_.isEmpty()) | |||
{ | |||
registerId_ = id; | |||
return true; | |||
} | |||
else if(registerId2_.isEmpty()) | |||
{ | |||
registerId2_ = id; | |||
return true; | |||
} | |||
return false; | |||
} | |||
void Comparator::setRegisterValue(const QString ®isterId, quint16 value) | |||
@@ -101,6 +104,9 @@ void Comparator::handleMenuAction(QAction *action) | |||
if (action->text() == "比较"){ | |||
emit requestCompare(this); | |||
} | |||
if (action->text() == "重置") { | |||
emit requestReset(this); | |||
} | |||
} | |||
void Comparator::setCompare(QString compare) | |||
@@ -118,3 +124,27 @@ bool Comparator::state() const | |||
if (compare_ == "<") return registerValue_ <= registerValue2_; | |||
return false; | |||
} | |||
QStringList Comparator::resetRegister() | |||
{ | |||
QStringList unboundRegs; | |||
// 重置第一个寄存器 | |||
if (!registerId_.isEmpty()) { | |||
unboundRegs << registerId_; | |||
registerId_.clear(); | |||
} | |||
// 重置第二个寄存器 | |||
if (!registerId2_.isEmpty()) { | |||
unboundRegs << registerId2_; | |||
registerId2_.clear(); | |||
} | |||
// 清除寄存器值 | |||
registerValue_ = 0; | |||
registerValue2_ = 0; | |||
update(); // 刷新显示 | |||
return unboundRegs; | |||
} |
@@ -10,12 +10,13 @@ public: | |||
void paint(QPainter *painter, | |||
const QStyleOptionGraphicsItem *option, | |||
QWidget *) override; | |||
void setRegisterId(const QString &id) override; | |||
bool setRegisterId(const QString &id) override; | |||
void setRegisterValue(const QString ®isterId, quint16 value) override; | |||
void addMenuActions(QMenu *menu) override; | |||
void handleMenuAction(QAction *action) override; | |||
void setCompare(QString) override; | |||
bool state() const override; | |||
QStringList resetRegister() override; | |||
private: | |||
QString registerId2_; | |||
@@ -58,9 +58,14 @@ QString Item::itemType() | |||
return type_; | |||
} | |||
void Item::setRegisterId(const QString &id) | |||
bool Item::setRegisterId(const QString &id) | |||
{ | |||
registerId_ = id; | |||
if(registerId_.isEmpty()) | |||
{ | |||
registerId_ = id; | |||
return true; | |||
} | |||
return false; | |||
} | |||
void Item::setRegisterValue(const QString ®isterId, quint16 value) | |||
@@ -72,11 +77,24 @@ void Item::setRegisterValue(const QString ®isterId, quint16 value) | |||
} | |||
} | |||
QStringList Item::resetRegister() | |||
{ | |||
QStringList unboundRegs; | |||
if (!registerId_.isEmpty()) { | |||
unboundRegs << registerId_; | |||
registerId_.clear(); | |||
registerValue_ = 0; | |||
update(); | |||
} | |||
return unboundRegs; | |||
} | |||
void Item::MenuActions(QMenu *menu) | |||
{ | |||
menu->addAction("复制"); | |||
menu->addAction("删除"); | |||
menu->addAction("对象"); | |||
menu->addAction("重置"); | |||
} | |||
void Item::addMenuActions(QMenu *menu) | |||
@@ -95,6 +113,9 @@ void Item::handleMenuAction(QAction *action) | |||
if (action->text() == "对象"){ | |||
emit requestBindRegister(this); | |||
} | |||
if (action->text() == "重置"){ | |||
emit requestReset(this); | |||
} | |||
} | |||
QVariant Item::itemChange(GraphicsItemChange change, const QVariant &value) | |||
@@ -21,10 +21,11 @@ public: | |||
void removeConnection(Connection* conn); | |||
QList<Connection*> connections(); | |||
QString itemType(); | |||
virtual void setRegisterId(const QString& id) { registerId_ = id; } | |||
virtual bool setRegisterId(const QString& id); | |||
QString registerId() const { return registerId_; } | |||
virtual void setRegisterValue(const QString& registerId, quint16 value); | |||
quint16 registerValue() const { return registerValue_; } | |||
virtual QStringList resetRegister(); | |||
virtual void setCompare(QString) {} | |||
@@ -37,6 +38,7 @@ signals: | |||
void requestDelete(Item*); | |||
void requestBindRegister(Item*); | |||
void requestCompare(Item*); | |||
void requestReset(Item*); | |||
protected: | |||
void MenuActions(QMenu *menu); | |||
@@ -1,53 +0,0 @@ | |||
#ifndef ITEM_H | |||
#define ITEM_H | |||
#include <QGraphicsObject> | |||
#include <QColor> | |||
#include <QList> | |||
#include <QAction> | |||
class Connection; | |||
class Item : public QGraphicsObject | |||
{ | |||
Q_OBJECT | |||
public: | |||
enum AnchorType { Left, Right }; | |||
explicit Item(const QString &type, QGraphicsItem *parent = nullptr); | |||
QRectF boundingRect() const override; | |||
QPointF anchorPos(AnchorType type) const; | |||
void addConnection(Connection* conn); | |||
void removeConnection(Connection* conn); | |||
QList<Connection*> connections(); | |||
QString itemType(); | |||
virtual void setRegisterId(const QString& id); | |||
QString registerId() const { return registerId_; } | |||
virtual void setRegisterValue(const QString& registerId, quint16 value); | |||
quint16 registerValue() const { return registerValue_; } | |||
virtual void setCompare(QString) {} | |||
// 添加状态属性(用于线圈、触点等) | |||
virtual bool state() const { return false; } | |||
signals: | |||
void requestCopy(Item*); | |||
void requestDelete(Item*); | |||
void requestBindRegister(Item*); | |||
void requestCompare(Item*); | |||
protected: | |||
void MenuActions(QMenu *menu); | |||
virtual void addMenuActions(QMenu *menu); | |||
virtual void handleMenuAction(QAction *action); | |||
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; | |||
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; | |||
QString type_; | |||
QList<Connection*> connections_; | |||
QString registerId_; | |||
quint16 registerValue_ = 0; | |||
}; | |||
#endif // ITEM_H |
@@ -51,6 +51,7 @@ void MyGraphicsView::dropEvent(QDropEvent *event) | |||
connect(item, &Item::requestDelete, this, &MyGraphicsView::onItemRequestDelete); | |||
connect(item, &Item::requestBindRegister, this, &MyGraphicsView::onItemRequestBindRegister); | |||
connect(item, &Item::requestCompare, this, &MyGraphicsView::onItemRequestCompare); | |||
connect(item, &Item::requestReset, this, &MyGraphicsView::onItemRequestReset); | |||
scene()->addItem(item); | |||
event->acceptProposedAction(); | |||
@@ -98,6 +99,8 @@ void MyGraphicsView::keyPressEvent(QKeyEvent *event) | |||
connect(newItem, &Item::requestCopy, this, &MyGraphicsView::onItemRequestCopy); | |||
connect(newItem, &Item::requestDelete, this, &MyGraphicsView::onItemRequestDelete); | |||
connect(newItem, &Item::requestBindRegister, this, &MyGraphicsView::onItemRequestBindRegister); | |||
connect(newItem, &Item::requestCompare, this, &MyGraphicsView::onItemRequestCompare); | |||
connect(newItem, &Item::requestReset, this, &MyGraphicsView::onItemRequestReset); | |||
scene()->addItem(newItem); | |||
} | |||
} else { | |||
@@ -119,6 +122,8 @@ void MyGraphicsView::contextMenuEvent(QContextMenuEvent *event) | |||
connect(newItem, &Item::requestCopy, this, &MyGraphicsView::onItemRequestCopy); | |||
connect(newItem, &Item::requestDelete, this, &MyGraphicsView::onItemRequestDelete); | |||
connect(newItem, &Item::requestBindRegister, this, &MyGraphicsView::onItemRequestBindRegister); | |||
connect(newItem, &Item::requestCompare, this, &MyGraphicsView::onItemRequestCompare); | |||
connect(newItem, &Item::requestReset, this, &MyGraphicsView::onItemRequestReset); | |||
scene()->addItem(newItem); | |||
} | |||
} else { | |||
@@ -202,11 +207,16 @@ void MyGraphicsView::onItemRequestBindRegister(Item *item) | |||
// 标准化格式 (D100) | |||
QString newReg = QString("%1%2").arg(reg[0].toUpper()).arg(address); | |||
item->setRegisterId(newReg); | |||
item->update(); | |||
// 发出绑定信号 | |||
emit itemBoundToRegister(item, newReg); | |||
if (item->setRegisterId(newReg)) | |||
{ | |||
item->update(); | |||
// 发出绑定信号 | |||
emit itemBoundToRegister(item, newReg); | |||
} | |||
else | |||
{ | |||
QMessageBox::warning(this, "提示", "请先重置再绑定新的寄存器"); | |||
} | |||
} | |||
} | |||
@@ -223,6 +233,14 @@ void MyGraphicsView::onItemRequestCompare(Item *item) | |||
item->setCompare(compare); | |||
} | |||
void MyGraphicsView::onItemRequestReset(Item *item) | |||
{ | |||
QStringList unboundRegs = item->resetRegister(); | |||
for (const QString& reg : unboundRegs) { | |||
emit itemResetRegister(item, reg); // 解绑每个寄存器 | |||
} | |||
} | |||
void MyGraphicsView::mousePressEvent(QMouseEvent *event) | |||
{ | |||
if (event->button() == Qt::LeftButton) { | |||
@@ -30,6 +30,7 @@ protected: | |||
signals: | |||
void itemBoundToRegister(Item*, QString); | |||
void itemResetRegister(Item*, QString); | |||
private: | |||
Item* anchorItemAt(const QPoint& viewPos, Item::AnchorType& anchorType); | |||
@@ -49,6 +50,7 @@ public slots: | |||
void onItemRequestDelete(Item*); | |||
void onItemRequestBindRegister(Item*); | |||
void onItemRequestCompare(Item*); | |||
void onItemRequestReset(Item*); | |||
}; | |||
#endif // MYGRAPHICSVIEW_H |
@@ -41,6 +41,8 @@ PLC::PLC(RegisterManager *regManager, QWidget *parent) : | |||
// this, &PLC::handleModbusError); | |||
connect(ui->graphicsView, &MyGraphicsView::itemBoundToRegister, | |||
registerManager, &RegisterManager::bindItem); | |||
connect(ui->graphicsView, &MyGraphicsView::itemResetRegister, | |||
registerManager, &RegisterManager::unbindItem); | |||
// connect(this, &PLC::requestWriteRegister, | |||
// modbusManager, &ModbusManager::writeRegister); | |||
} | |||
@@ -22,6 +22,23 @@ void RegisterManager::bindItem(Item* item, const QString& registerId) | |||
}); | |||
} | |||
void RegisterManager::unbindItem(Item *item, const QString ®isterId) | |||
{ | |||
if (registerMap.contains(registerId)) { | |||
// 从寄存器映射中移除元件 | |||
QList<Item*>& items = registerMap[registerId]; | |||
items.removeAll(item); | |||
// 如果列表为空则移除整个条目 | |||
if (items.isEmpty()) { | |||
registerMap.remove(registerId); | |||
} | |||
// 断开该寄存器的销毁信号连接 | |||
disconnect(item, &Item::destroyed, this, nullptr); | |||
} | |||
} | |||
void RegisterManager::updateRegisterValue(const QString& registerId, quint16 value) | |||
{ | |||
if (!registerMap.contains(registerId)) return; | |||
@@ -12,6 +12,7 @@ public: | |||
// 注册图元与寄存器绑定关系 | |||
void bindItem(Item* item, const QString& registerId); | |||
void unbindItem(Item* item, const QString& registerId); | |||
// 更新寄存器值 | |||
void updateRegisterValue(const QString& registerId, quint16 value); | |||