diff --git a/hmi.cpp b/hmi.cpp index 58429f6..bd7a658 100644 --- a/hmi.cpp +++ b/hmi.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "creatitem.h" HMI::HMI(QWidget *parent) : @@ -15,11 +16,9 @@ HMI::HMI(QWidget *parent) : ui(new Ui::HMI) { ui->setupUi(this); - /* 1. 场景 */ - hmi_scene_ = new QGraphicsScene(this); - ui->graphicsView->setScene(hmi_scene_); - ui->graphicsView->setSceneRect(0, 0, 800, 600); - ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag); + + ui->tabWidget->setTabsClosable(true); + ui->tabWidget->setMovable(true); /* 2. 列表 */ ui->listWidget->setViewMode(QListView::IconMode); @@ -27,16 +26,53 @@ HMI::HMI(QWidget *parent) : ui->listWidget->setDragEnabled(false); ui->listWidget->viewport()->installEventFilter(this); + // 创建初始页面 + newPage(); + /* 3. 填充列表 */ createComponents(); connect(ui->listWidget,&QListWidget::currentTextChanged,this,&HMI::onListwidgetCurrenttextchanged); + + // 连接标签页信号 +// connect(ui->tabWidget, &QTabWidget::currentChanged, this, &HMI::onTabChanged); + connect(ui->tabWidget, &QTabWidget::tabCloseRequested, [this](int index) { + if (scenes.size() > 1) { + delete scenes.takeAt(index); + delete views.takeAt(index); + ui->tabWidget->removeTab(index); + } else { + QMessageBox::information(this, "提示", "至少保留一个页面"); + } + }); } HMI::~HMI() { + qDeleteAll(scenes); + qDeleteAll(views); delete ui; } +void HMI::newPage() +{ + // 创建新场景 + QGraphicsScene* newScene = new QGraphicsScene(this); + + // 创建新视图 + MyGraphicsView* newView = new MyGraphicsView(ui->tabWidget); + newView->setScene(newScene); + newView->setSceneRect(0, 0, 800, 600); + newView->setDragMode(QGraphicsView::RubberBandDrag); + + // 添加到标签页 + int newIndex = ui->tabWidget->addTab(newView, QString("页面 %1").arg(scenes.size() + 1)); + ui->tabWidget->setCurrentIndex(newIndex); + + // 保存场景和视图 + scenes.append(newScene); + views.append(newView); +} + bool HMI::eventFilter(QObject *obj, QEvent *event) { if (obj == ui->listWidget->viewport()) { @@ -102,32 +138,43 @@ void HMI::createComponents() void HMI::clearScene() { - hmi_scene_->clear(); + if (currentPageIndex() >= 0 && currentPageIndex() < scenes.size()) { + scenes[currentPageIndex()]->clear(); + } } -void HMI::applyProjectToScene(const Project& proj) +int HMI::currentPageIndex() const { - clearScene(); + return ui->tabWidget->currentIndex(); +} + +void HMI::applyProjectToScene(const Project& proj, int pageIndex) +{ + if (pageIndex < 0 || pageIndex >= scenes.size()) + return; + + scenes[pageIndex]->clear(); QVector itemObjs; for (const auto& d : proj.items_) { Item* item = creatItem(d.type); if (!item) continue; item->setPos(d.x, d.y); item->setRegisterId(d.registerId); - connect(item, &Item::requestCopy, ui->graphicsView, &MyGraphicsView::onItemRequestCopy); - connect(item, &Item::requestDelete, ui->graphicsView, &MyGraphicsView::onItemRequestDelete); - connect(item, &Item::requestBindRegister, ui->graphicsView, &MyGraphicsView::onItemRequestBindRegister); - hmi_scene_->addItem(item); + connect(item, &Item::requestCopy, views[pageIndex], &MyGraphicsView::onItemRequestCopy); + connect(item, &Item::requestDelete, views[pageIndex], &MyGraphicsView::onItemRequestDelete); + connect(item, &Item::requestBindRegister, views[pageIndex], &MyGraphicsView::onItemRequestBindRegister); + scenes[pageIndex]->addItem(item); itemObjs.append(item); } } -void HMI::extractSceneToProject(Project& proj) +void HMI::extractSceneToProject(Project& proj, int pageIndex) { + if (pageIndex < 0 || pageIndex >= scenes.size()) return; proj.clear(); QList items; - for (QGraphicsItem* gi : hmi_scene_->items()) { - if (Item* it = dynamic_cast(gi)) { + for (QGraphicsItem* gi : scenes[pageIndex]->items()){ + if (Item* it = dynamic_cast(gi)){ items.append(it); } } @@ -139,7 +186,7 @@ void HMI::extractSceneToProject(Project& proj) d.registerId = it->registerId(); proj.items_.append(d); } - for (QGraphicsItem* gi : hmi_scene_->items()) { + for (QGraphicsItem* gi : scenes[pageIndex]->items()) { if (Connection* conn = dynamic_cast(gi)) { int fromIdx = items.indexOf(conn->from_); int toIdx = items.indexOf(conn->to_); diff --git a/hmi.h b/hmi.h index d2eb0c4..dd0557d 100644 --- a/hmi.h +++ b/hmi.h @@ -4,6 +4,7 @@ #include #include #include +#include "mygraphicsview.h" namespace Ui { class HMI; @@ -16,11 +17,13 @@ class HMI : public QWidget public: explicit HMI(QWidget *parent = nullptr); ~HMI(); + void newPage(); void createComponents(); void clearScene(); - void applyProjectToScene(const Project& proj); - void extractSceneToProject(Project& proj); + void applyProjectToScene(const Project& proj, int pageIndex = 0); // 添加页面索引参数 + void extractSceneToProject(Project& proj, int pageIndex = 0); // 添加页面索引参数 + int currentPageIndex() const; // 获取当前页面索引 protected: bool eventFilter(QObject *obj, QEvent *event) override; @@ -30,7 +33,8 @@ private slots: private: Ui::HMI *ui; - QGraphicsScene *hmi_scene_; + QList scenes; // 存储多个场景 + QList views; // 存储多个视图 QString selectedComponentType; }; diff --git a/hmi.ui b/hmi.ui index 5e74625..9d3dbeb 100644 --- a/hmi.ui +++ b/hmi.ui @@ -19,7 +19,7 @@ 10 30 171 - 451 + 431 @@ -29,44 +29,14 @@ 190 10 781 - 481 + 451 - 0 + -1 - - - Tab 1 - - - - - 0 - 0 - 761 - 451 - - - - QGraphicsView::NoDrag - - - - - - Tab 2 - - - - - MyGraphicsView - QGraphicsView -
mygraphicsview.h
-
-
diff --git a/mainwindow.cpp b/mainwindow.cpp index 8d38fa6..a5aa795 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -35,7 +35,7 @@ MainWindow::MainWindow(QWidget *parent) connect(ui->action_disconnect, &QAction::triggered, this, &MainWindow::disconnection); connect(modbusManager, &ModbusManager::connectionStatusChanged, - plc_, &PLC::updateConnectionStatus); + this, &MainWindow::updateConnectionStatus); plc_->applyProjectToScene(plcProject_); // 初始空 @@ -71,9 +71,11 @@ void MainWindow::newProject() plc_->clearScene(); setWindowTitle("未命名项目 - PLC编辑器"); } else { - hmiProject_.clear(); + hmi_->newPage(); + hmiProject_.clear(); // 清除项目数据 hmiFilePath_.clear(); - hmi_->clearScene(); + + // 更新窗口标题 setWindowTitle("未命名项目 - HMI编辑器"); } } @@ -99,14 +101,20 @@ void MainWindow::openProject() { QString filePath = QFileDialog::getOpenFileName(this, "打开项目", "", "项目文件 (*.hmiproj)"); if (filePath.isEmpty()) return; - if (hmiProject_.loadFromFile(filePath)) - { + + Project newProject; + if (newProject.loadFromFile(filePath)) { + // 创建新页面 + hmi_->newPage(); + + // 应用项目到新页面 + int newPageIndex = hmi_->currentPageIndex(); + hmi_->applyProjectToScene(newProject, newPageIndex); + + // 保存文件路径 hmiFilePath_ = filePath; - hmi_->applyProjectToScene(hmiProject_); setWindowTitle(QFileInfo(hmiFilePath_).fileName() + " - HMI编辑器"); - } - else - { + } else { QMessageBox::critical(this, "错误", "无法打开HMI项目文件"); } } @@ -134,7 +142,10 @@ void MainWindow::saveProject() filePath += ".hmiproj"; hmiFilePath_ = filePath; } - hmi_->extractSceneToProject(hmiProject_); + + // 从当前页面提取项目 + hmi_->extractSceneToProject(hmiProject_, hmi_->currentPageIndex()); + if (!hmiProject_.saveToFile(hmiFilePath_)) { QMessageBox::critical(this, "错误", "保存项目失败"); } @@ -152,3 +163,15 @@ void MainWindow::disconnection() modbusManager->disconnectDevice(); modbusManager->stopSimulation(); } + +void MainWindow::updateConnectionStatus(bool connection) +{ + if (connection) + { + ui->textEdit->append("连接"); + } + else + { + ui->textEdit->append("断开"); + } +} diff --git a/mainwindow.h b/mainwindow.h index b54ff0a..f8dd4d0 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -28,6 +28,7 @@ private slots: void saveProject(); void connection(); void disconnection(); + void updateConnectionStatus(bool connection); private: Ui::MainWindow *ui; diff --git a/mainwindow.ui b/mainwindow.ui index 300e9d9..f658dfc 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -20,7 +20,17 @@ 10 0 981 - 561 + 511 + + + + + + + 20 + 470 + 951 + 141 diff --git a/plc.cpp b/plc.cpp index dc95121..26e4122 100644 --- a/plc.cpp +++ b/plc.cpp @@ -237,14 +237,14 @@ void PLC::btnInsertClicked() ui->graphicsView->scene()->addItem(c2); } -void PLC::updateConnectionStatus(bool connection) -{ - if (connection) - { - ui->textEdit->append("连接"); - } - else - { - ui->textEdit->append("断开"); - } -} +//void PLC::updateConnectionStatus(bool connection) +//{ +// if (connection) +// { +// ui->textEdit->append("连接"); +// } +// else +// { +// ui->textEdit->append("断开"); +// } +//} diff --git a/plc.h b/plc.h index 04e4fc7..27b482d 100644 --- a/plc.h +++ b/plc.h @@ -30,7 +30,7 @@ public slots: void onListwidgetCurrenttextchanged(const QString ¤tText); void btnInsertClicked(); - void updateConnectionStatus(bool connection); +// void updateConnectionStatus(bool connection); private: Ui::PLC *ui; diff --git a/plc.ui b/plc.ui index b7189f9..c98068d 100644 --- a/plc.ui +++ b/plc.ui @@ -19,7 +19,7 @@ 10 30 171 - 401 + 431 @@ -29,7 +29,7 @@ 200 30 761 - 401 + 431 @@ -49,16 +49,6 @@ 插入 - - - - 10 - 440 - 951 - 87 - - -