@@ -31,6 +31,7 @@ SOURCES += \ | |||||
mainwindow.cpp \ | mainwindow.cpp \ | ||||
modbusmanager.cpp \ | modbusmanager.cpp \ | ||||
mygraphicsview.cpp \ | mygraphicsview.cpp \ | ||||
myscene.cpp \ | |||||
plc.cpp \ | plc.cpp \ | ||||
project.cpp \ | project.cpp \ | ||||
registermanager.cpp | registermanager.cpp | ||||
@@ -48,6 +49,7 @@ HEADERS += \ | |||||
mainwindow.h \ | mainwindow.h \ | ||||
modbusmanager.h \ | modbusmanager.h \ | ||||
mygraphicsview.h \ | mygraphicsview.h \ | ||||
myscene.h \ | |||||
plc.h \ | plc.h \ | ||||
project.h \ | project.h \ | ||||
registermanager.h | registermanager.h | ||||
@@ -1,5 +1,6 @@ | |||||
#include "item.h" | #include "item.h" | ||||
#include "connection.h" | #include "connection.h" | ||||
#include "myscene.h" | |||||
#include <QMenu> | #include <QMenu> | ||||
#include <QPainter> | #include <QPainter> | ||||
#include <QStyleOptionGraphicsItem> | #include <QStyleOptionGraphicsItem> | ||||
@@ -120,9 +121,52 @@ void Item::handleMenuAction(QAction *action) | |||||
QVariant Item::itemChange(GraphicsItemChange change, const QVariant &value) | QVariant Item::itemChange(GraphicsItemChange change, const QVariant &value) | ||||
{ | { | ||||
if (change == QGraphicsItem::ItemPositionChange) { | |||||
for (Connection* conn : connections_) | |||||
conn->updatePosition(); | |||||
// if (change == QGraphicsItem::ItemPositionChange) { | |||||
// for (Connection* conn : connections_) | |||||
// conn->updatePosition(); | |||||
// } | |||||
// if (change == ItemPositionChange && scene()) { | |||||
// // 获取场景(确保是 GridScene) | |||||
// if (auto myScene = dynamic_cast<MyScene*>(scene())) { | |||||
// if (myScene->getSnapToGrid()) { | |||||
// // 获取网格大小 | |||||
// int gridSize = myScene->getGridSize(); | |||||
// // 对齐到网格 | |||||
// QPointF newPos = value.toPointF(); | |||||
// qreal xV = qRound(newPos.x() / gridSize) * gridSize; | |||||
// qreal yV = qRound(newPos.y() / gridSize) * gridSize; | |||||
// return QPointF(xV, yV); | |||||
// } | |||||
// } | |||||
// } | |||||
// 处理位置即将改变事件(网格对齐) | |||||
if (change == ItemPositionChange && scene()) { | |||||
QPointF newPos = value.toPointF(); | |||||
// 检查是否启用网格对齐 | |||||
if (auto myScene = dynamic_cast<MyScene*>(scene())) { | |||||
if (myScene->getSnapToGrid()) { | |||||
int gridSize = myScene->getGridSize(); | |||||
// 计算对齐位置 | |||||
qreal xV = qRound(newPos.x() / gridSize) * gridSize; | |||||
qreal yV = qRound(newPos.y() / gridSize) * gridSize; | |||||
// 返回对齐后的位置 | |||||
return QPointF(xV, yV); | |||||
} | |||||
} | |||||
} | |||||
// 处理位置已改变事件(更新连线) | |||||
else if (change == QGraphicsItem::ItemPositionHasChanged) { | |||||
// 使用范围for循环安全遍历(防止在更新过程中连接被修改) | |||||
QList<Connection*> connectionsCopy = connections_; | |||||
for (Connection* conn : connectionsCopy) { | |||||
if (connections_.contains(conn)) { // 确保连接仍然存在 | |||||
conn->updatePosition(); | |||||
} | |||||
} | |||||
} | } | ||||
return QGraphicsObject::itemChange(change, value); | return QGraphicsObject::itemChange(change, value); | ||||
} | } | ||||
@@ -76,16 +76,20 @@ MainWindow::~MainWindow() | |||||
void MainWindow::newPage(bool isPlc) | void MainWindow::newPage(bool isPlc) | ||||
{ | { | ||||
// 创建新场景 | |||||
QGraphicsScene* newScene = new QGraphicsScene(this); | |||||
// 创建新视图 | |||||
MyGraphicsView* newView = new MyGraphicsView(this); | |||||
newView->setScene(newScene); | |||||
newView->setSceneRect(0, 0, 800, 600); | |||||
newView->setDragMode(QGraphicsView::RubberBandDrag); | |||||
if (isPlc) { | if (isPlc) { | ||||
// 创建新场景 | |||||
MyScene* newScene = new MyScene(this); | |||||
// 设置网格属性 | |||||
newScene->setGridSize(20); // 20像素网格 | |||||
newScene->setGridColor(QColor(200, 200, 200, 150)); // 半透明灰色 | |||||
newScene->setSnapToGrid(true); // 启用对齐网格 | |||||
// 创建新视图 | |||||
MyGraphicsView* newView = new MyGraphicsView(this); | |||||
newView->setScene(newScene); | |||||
newView->setSceneRect(0, 0, 800, 600); | |||||
newView->setDragMode(QGraphicsView::RubberBandDrag); | |||||
// 添加到PLC标签页 | // 添加到PLC标签页 | ||||
int newIndex = ui->plc_tab_widget->addTab(newView, QString("页面 %1").arg(plcScenes.size() + 1)); | int newIndex = ui->plc_tab_widget->addTab(newView, QString("页面 %1").arg(plcScenes.size() + 1)); | ||||
plcPageTitles.append(""); // 初始化为空字符串 | plcPageTitles.append(""); // 初始化为空字符串 | ||||
@@ -99,6 +103,14 @@ void MainWindow::newPage(bool isPlc) | |||||
connect(newView, &MyGraphicsView::itemResetRegister, | connect(newView, &MyGraphicsView::itemResetRegister, | ||||
registerManager, &RegisterManager::unbindItem); | registerManager, &RegisterManager::unbindItem); | ||||
} else { | } else { | ||||
// 创建新场景 | |||||
QGraphicsScene* newScene = new QGraphicsScene(this); | |||||
// 创建新视图 | |||||
MyGraphicsView* newView = new MyGraphicsView(this); | |||||
newView->setScene(newScene); | |||||
newView->setSceneRect(0, 0, 800, 600); | |||||
newView->setDragMode(QGraphicsView::RubberBandDrag); | |||||
// 添加到HMI标签页 | // 添加到HMI标签页 | ||||
int newIndex = ui->hmi_tab_widget->addTab(newView, QString("页面 %1").arg(hmiScenes.size() + 1)); | int newIndex = ui->hmi_tab_widget->addTab(newView, QString("页面 %1").arg(hmiScenes.size() + 1)); | ||||
hmiPageTitles.append(""); // 初始化为空字符串 | hmiPageTitles.append(""); // 初始化为空字符串 | ||||
@@ -425,18 +437,18 @@ void MainWindow::hmiChange() | |||||
void MainWindow::newProject() | void MainWindow::newProject() | ||||
{ | { | ||||
// 检查当前tabwidget是否只有一个页面且页面内容为空 | |||||
if (currentIsPLC_ && plcScenes.size() == 1 && plcScenes[0]->items().isEmpty()) { | |||||
// 复用第一个页面 | |||||
clearScene(); | |||||
setWindowTitle("PLC编辑器"); | |||||
return; | |||||
} | |||||
if (!currentIsPLC_ && hmiScenes.size() == 1 && hmiScenes[0]->items().isEmpty()) { | |||||
clearScene(); | |||||
setWindowTitle("HMI编辑器"); | |||||
return; | |||||
} | |||||
// // 检查当前tabwidget是否只有一个页面且页面内容为空 | |||||
// if (currentIsPLC_ && plcScenes.size() == 1 && plcScenes[0]->items().isEmpty()) { | |||||
// // 复用第一个页面 | |||||
// clearScene(); | |||||
// setWindowTitle("PLC编辑器"); | |||||
// return; | |||||
// } | |||||
// if (!currentIsPLC_ && hmiScenes.size() == 1 && hmiScenes[0]->items().isEmpty()) { | |||||
// clearScene(); | |||||
// setWindowTitle("HMI编辑器"); | |||||
// return; | |||||
// } | |||||
newPage(currentIsPLC_); | newPage(currentIsPLC_); | ||||
// 更新窗口标题 | // 更新窗口标题 | ||||
@@ -569,10 +581,6 @@ void MainWindow::onListwidgetCurrenttextchanged(const QString ¤tText) | |||||
void MainWindow::onTabCloseRequested(int index) | void MainWindow::onTabCloseRequested(int index) | ||||
{ | { | ||||
if (plcScenes.size() == 1) { | |||||
QMessageBox::information(this, "提示", "至少保留一个页面"); | |||||
return; | |||||
} | |||||
if (currentIsPLC_) | if (currentIsPLC_) | ||||
{ | { | ||||
plcPageTitles.removeAt(index); | plcPageTitles.removeAt(index); | ||||
@@ -6,6 +6,7 @@ | |||||
#include "hmi.h" | #include "hmi.h" | ||||
#include "modbusmanager.h" | #include "modbusmanager.h" | ||||
#include "registermanager.h" | #include "registermanager.h" | ||||
#include "myscene.h" | |||||
QT_BEGIN_NAMESPACE | QT_BEGIN_NAMESPACE | ||||
namespace Ui { class MainWindow; } | namespace Ui { class MainWindow; } | ||||
@@ -47,7 +48,7 @@ private: | |||||
RegisterManager* registerManager; | RegisterManager* registerManager; | ||||
ModbusManager* modbusManager; | ModbusManager* modbusManager; | ||||
// PLC状态 | // PLC状态 | ||||
QList<QGraphicsScene*> plcScenes; | |||||
QList<MyScene*> plcScenes; | |||||
QList<MyGraphicsView*> plcViews; | QList<MyGraphicsView*> plcViews; | ||||
QStringList plcPageTitles; | QStringList plcPageTitles; | ||||
@@ -0,0 +1,34 @@ | |||||
#include "myscene.h" | |||||
#include <QPainter> | |||||
MyScene::MyScene(QObject *parent) : QGraphicsScene(parent) | |||||
{ | |||||
} | |||||
void MyScene::drawBackground(QPainter *painter, const QRectF &rect) | |||||
{ | |||||
QGraphicsScene::drawBackground(painter, rect); | |||||
// 设置画笔 | |||||
QPen pen(gridColor); | |||||
pen.setWidth(1); | |||||
painter->setPen(pen); | |||||
// 计算网格线 | |||||
qreal left = int(rect.left()) - (int(rect.left()) % gridSize); | |||||
qreal top = int(rect.top()) - (int(rect.top()) % gridSize); | |||||
QVarLengthArray<QLineF, 100> lines; | |||||
for (qreal x = left; x < rect.right(); x += gridSize) { | |||||
lines.append(QLineF(x, rect.top(), x, rect.bottom())); | |||||
} | |||||
for (qreal y = top; y < rect.bottom(); y += gridSize) { | |||||
lines.append(QLineF(rect.left(), y, rect.right(), y)); | |||||
} | |||||
// 绘制网格 | |||||
painter->drawLines(lines.data(), lines.size()); | |||||
} |
@@ -0,0 +1,30 @@ | |||||
#ifndef MYSCENE_H | |||||
#define MYSCENE_H | |||||
#include <QGraphicsScene> | |||||
class MyScene : public QGraphicsScene | |||||
{ | |||||
Q_OBJECT | |||||
public: | |||||
explicit MyScene(QObject *parent = nullptr); | |||||
// 网格属性设置 | |||||
void setGridSize(int size) { gridSize = size; } | |||||
int getGridSize() const { return gridSize; } | |||||
void setGridColor(const QColor &color) { gridColor = color; } | |||||
QColor getGridColor() const { return gridColor; } | |||||
void setSnapToGrid(bool snap) { snapToGrid = snap; } | |||||
bool getSnapToGrid() const { return snapToGrid; } | |||||
void drawBackground(QPainter *painter, const QRectF &rect) override; | |||||
private: | |||||
int gridSize = 20; // 网格大小(像素) | |||||
QColor gridColor = QColor(220, 220, 220); // 网格颜色(浅灰色) | |||||
bool snapToGrid = true; // 是否启用对齐网格 | |||||
}; | |||||
#endif // MYSCENE_H |