diff --git a/customgraphics.cpp b/customgraphics.cpp index 1d49125..fe02e84 100644 --- a/customgraphics.cpp +++ b/customgraphics.cpp @@ -82,35 +82,38 @@ void HmiComponent::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) // HmiButton 类实现 - -HmiButton::HmiButton(QGraphicsItem *parent) : HmiComponent(parent) { +HmiButton::HmiButton(QGraphicsItem *parent) : HmiComponent(parent) +{ m_color = Qt::gray; m_componentName = "Button"; } -QRectF HmiButton::boundingRect() const { - return QRectF(0, 0, 80, 30); +QRectF HmiButton::boundingRect() const +{ + return QRectF(0, 0, 65, 30); } -void HmiButton::paintShape(QPainter *painter) { +void HmiButton::paintShape(QPainter *painter) +{ painter->setPen(Qt::NoPen); painter->setBrush(m_color); painter->drawRect(boundingRect()); } - // HmiIndicator 类实现 - -HmiIndicator::HmiIndicator(QGraphicsItem *parent) : HmiComponent(parent) { +HmiIndicator::HmiIndicator(QGraphicsItem *parent) : HmiComponent(parent) +{ m_color = Qt::green; m_componentName = "Indicator"; } -QRectF HmiIndicator::boundingRect() const { +QRectF HmiIndicator::boundingRect() const +{ return QRectF(0, 0, 30, 30); } -void HmiIndicator::paintShape(QPainter *painter) { +void HmiIndicator::paintShape(QPainter *painter) +{ painter->setPen(Qt::NoPen); painter->setBrush(m_color); painter->drawEllipse(boundingRect()); diff --git a/hmimodule.cpp b/hmimodule.cpp index 554aaee..33d6fbd 100644 --- a/hmimodule.cpp +++ b/hmimodule.cpp @@ -1,14 +1,16 @@ #include "hmimodule.h" #include -#include // --- 确保包含 QGraphicsView 头文件 --- +#include #include +#include +#include +#include +#include // 引入 std::sort -// HMIModule 构造函数无需改动 HMIModule::HMIModule(Ui::MainWindow* ui, QObject *parent) : QObject{parent}, ui_(ui), m_scene(nullptr) {} -// 封装设置图标和大小的通用函数 void HMIModule::setButtonIcon(QAbstractButton *button, const QString &iconPath) { button->setIcon(QIcon(iconPath)); @@ -24,7 +26,6 @@ void HMIModule::init() { setButtonIcon(ui_->nextPage, ":/resource/image/next.png"); if (!ui_->hmiGraphicsView->scene()) { - // 创建场景时,将 view 指针传入 m_scene = new CustomGraphicsScene(ui_->hmiGraphicsView, this); m_scene->setSceneRect(0, 0, 800, 600); ui_->hmiGraphicsView->setScene(m_scene); @@ -36,22 +37,25 @@ void HMIModule::init() { connect(ui_->button, &QPushButton::clicked, this, &HMIModule::prepareToCreateButton); connect(ui_->lamp, &QPushButton::clicked, this, &HMIModule::prepareToCreateIndicator); connect(m_scene, &CustomGraphicsScene::componentCreated, this, &HMIModule::onComponentCreated); - // 连接来自场景的键盘事件信号 connect(m_scene, &CustomGraphicsScene::copyRequestFromScene, this, &HMIModule::onCopyRequested); connect(m_scene, &CustomGraphicsScene::pasteRequestFromScene, this, &HMIModule::onPasteRequested); connect(m_scene, &CustomGraphicsScene::deleteRequestFromScene, this, &HMIModule::onDeleteRequested); + + // 连接新增的槽函数 + connect(ui_->addPage, &QPushButton::clicked, this, &HMIModule::addPage); + connect(ui_->deletePage, &QPushButton::clicked, this, &HMIModule::deletePage); + connect(ui_->prePage, &QPushButton::clicked, this, &HMIModule::prePage); + connect(ui_->nextPage, &QPushButton::clicked, this, &HMIModule::nextPage); } -// 辅助函数,用于设置新创建的组件 + void HMIModule::setupNewComponent(HmiComponent* item) { if (!item) return; - // 连接所有需要的信号 connect(item, &HmiComponent::selected, this, &HMIModule::onComponentSelected); connect(item, &HmiComponent::copyRequested, this, &HMIModule::onCopyRequested); connect(item, &HmiComponent::deleteRequested, this, &HMIModule::onDeleteRequested); - // 生成日志 QString currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); QString log = QString("[%1] 创建 %2 组件") .arg(currentTime) @@ -59,21 +63,18 @@ void HMIModule::setupNewComponent(HmiComponent* item) emit logMessageGenerated(log); } -// 准备创建按钮的槽函数 void HMIModule::prepareToCreateButton() { m_scene->setComponentTypeToCreate(ComponentType::Button); m_scene->setMode(CustomGraphicsScene::Mode::CreateItem); } -// 准备创建指示灯的槽函数 void HMIModule::prepareToCreateIndicator() { m_scene->setComponentTypeToCreate(ComponentType::Indicator); m_scene->setMode(CustomGraphicsScene::Mode::CreateItem); } -// 处理新创建组件的槽函数 void HMIModule::onComponentCreated(HmiComponent* item) { setupNewComponent(item); @@ -84,11 +85,9 @@ void HMIModule::onCopyRequested() QList selected = m_scene->selectedItems(); if (selected.isEmpty()) return; - // 只复制第一个选中的项目 HmiComponent* itemToCopy = qgraphicsitem_cast(selected.first()); if (!itemToCopy) return; - // 存储组件信息到 "剪贴板" if (dynamic_cast(itemToCopy)) { m_copiedType = ComponentType::Button; } else if (dynamic_cast(itemToCopy)) { @@ -97,7 +96,6 @@ void HMIModule::onCopyRequested() m_copiedColor = itemToCopy->color(); m_hasCopiedItem = true; - // 日志 emit logMessageGenerated(QString("[%1] 复制组件: %2") .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) .arg(itemToCopy->componentName())); @@ -116,12 +114,8 @@ void HMIModule::onPasteRequested(const QPointF& scenePos) if (newItem) { newItem->setColor(m_copiedColor); - // 为了避免完全重叠,给一个小的偏移量 newItem->setPos(scenePos); m_scene->addItem(newItem); - - // 使用辅助函数完成添加和信号连接 - // 注意:setupNewComponent内部会再次生成“创建”日志,这里是合理的 setupNewComponent(newItem); } } @@ -131,25 +125,111 @@ void HMIModule::onDeleteRequested() QList selected = m_scene->selectedItems(); if (selected.isEmpty()) return; - // 日志 emit logMessageGenerated(QString("[%1] 删除 %2 个组件") .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) .arg(selected.count())); - // 从后往前删,避免迭代器失效问题 for (int i = selected.count() - 1; i >= 0; --i) { QGraphicsItem* item = selected.at(i); m_scene->removeItem(item); - delete item; // 释放内存 + delete item; } } -// 统一处理选中事件的槽函数,无需修改 void HMIModule::onComponentSelected(HmiComponent* item) { - // if (item) { - // qDebug() << "Component selected:" << item->componentName() - // << "Color:" << item->color(); - // // 未来可以在这里将item对象传递给属性编辑器 - // } +} + +// 新增页面的槽函数 +void HMIModule::addPage() +{ + QTabWidget* tabWidget = ui_->tabWidget_2; // 获取TabWidget + int pageNumber; + + // 检查是否有可用的页面编号 + if (!m_availablePageNumbers.isEmpty()) { + // 获取最小的可用的页面编号 (QList 已经是有序的) + pageNumber = m_availablePageNumbers.first(); + m_availablePageNumbers.removeFirst(); + } else { + // 如果没有可用的页面编号,则使用 m_pageCount 并递增 + pageNumber = ++m_pageCount; + } + + // 创建新的页面部件 + QWidget* newPage = new QWidget(tabWidget); + QString pageName = QString("Page %1").arg(pageNumber); + newPage->setObjectName(pageName); + + // 创建新的 GraphicsView 和 Scene + QGraphicsView* newGraphicsView = new QGraphicsView(newPage); + CustomGraphicsScene* newScene = new CustomGraphicsScene(newGraphicsView, this); + newScene->setSceneRect(0, 0, 800, 600); + newGraphicsView->setScene(newScene); + + // 布局 + QVBoxLayout* layout = new QVBoxLayout(newPage); + layout->addWidget(newGraphicsView); + newPage->setLayout(layout); + + // 添加到 TabWidget + tabWidget->addTab(newPage, pageName); + tabWidget->setCurrentWidget(newPage); + + //记录日志 + emit logMessageGenerated(QString("[%1] 添加页面: %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(pageName)); +} + +// 删除页面的槽函数 +void HMIModule::deletePage() +{ + QTabWidget* tabWidget = ui_->tabWidget_2; + int currentIndex = tabWidget->currentIndex(); + + if (tabWidget->count() == 1) { + QMessageBox::information(nullptr, "提示", "这是最后一页,不能删除!"); + return; + } + + if (currentIndex >= 0) { + // 获取要删除的页面 + QWidget* currentPage = tabWidget->widget(currentIndex); + QString pageName = tabWidget->tabText(currentIndex); + + // 从页面名称中提取页面编号 + int pageNumber = pageName.remove("Page ").toInt(); + + // 将删除的页面编号添加到可用列表中,并保持列表有序 + m_availablePageNumbers.append(pageNumber); + std::sort(m_availablePageNumbers.begin(), m_availablePageNumbers.end()); + + // 从 TabWidget 中移除页面 + tabWidget->removeTab(currentIndex); + + // 删除页面 + delete currentPage; + + // 记录日志 + emit logMessageGenerated(QString("[%1] 删除页面: %2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")).arg(pageName)); + } +} + +// 前一页的槽函数 +void HMIModule::prePage() +{ + QTabWidget* tabWidget = ui_->tabWidget_2; + int currentIndex = tabWidget->currentIndex(); + if (currentIndex > 0) { + tabWidget->setCurrentIndex(currentIndex - 1); + } +} + +// 后一页的槽函数 +void HMIModule::nextPage() +{ + QTabWidget* tabWidget = ui_->tabWidget_2; + int currentIndex = tabWidget->currentIndex(); + if (currentIndex < tabWidget->count() - 1) { + tabWidget->setCurrentIndex(currentIndex + 1); + } } diff --git a/hmimodule.h b/hmimodule.h index 45596d5..d5ca8f5 100644 --- a/hmimodule.h +++ b/hmimodule.h @@ -3,8 +3,8 @@ #include #include "ui_MainWindow.h" -// #include "customgraphics.h" // 已被 customgraphicsscene.h 包含 -#include "customgraphicsscene.h" // 引入新的场景头文件 +#include "customgraphicsscene.h" +#include // 引入 QList class HMIModule : public QObject { @@ -15,21 +15,20 @@ public: void init(); private slots: - // 准备创建组件,而不是直接创建 void prepareToCreateButton(); void prepareToCreateIndicator(); - - // 当场景创建了一个组件后,进行后续处理 void onComponentCreated(HmiComponent* item); - void onComponentSelected(HmiComponent* item); - - // 处理复制、粘贴、删除的槽函数 void onCopyRequested(); void onPasteRequested(const QPointF& scenePos); void onDeleteRequested(); - // 一个用于发送日志消息的信号 + // 新增的槽函数 + void addPage(); + void deletePage(); + void prePage(); + void nextPage(); + signals: void logMessageGenerated(const QString& message); @@ -39,11 +38,11 @@ private: private: Ui::MainWindow* ui_; CustomGraphicsScene* m_scene; - - // 用于实现剪贴板功能的成员变量 ComponentType m_copiedType; QColor m_copiedColor; bool m_hasCopiedItem = false; + int m_pageCount = 1; // 初始化页面计数器 + QList m_availablePageNumbers; // 用于存储可用的页面编号 (有序列表) }; #endif // HMIMODULE_H