Sfoglia il codice sorgente

实现新增删除页面的功能,并且删除页面后新建时能优先新建刚刚删除的页数

master
付春阳 3 giorni fa
parent
commit
bcd5fb4a41
3 ha cambiato i file con 130 aggiunte e 48 eliminazioni
  1. +13
    -10
      customgraphics.cpp
  2. +107
    -27
      hmimodule.cpp
  3. +10
    -11
      hmimodule.h

+ 13
- 10
customgraphics.cpp Vedi File

@@ -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());


+ 107
- 27
hmimodule.cpp Vedi File

@@ -1,14 +1,16 @@
#include "hmimodule.h"
#include <QGraphicsScene>
#include <QGraphicsView> // --- 确保包含 QGraphicsView 头文件 ---
#include <QGraphicsView>
#include <QDateTime>
#include <QTabWidget>
#include <QMessageBox>
#include <QVBoxLayout>
#include <algorithm> // 引入 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<QGraphicsItem*> selected = m_scene->selectedItems();
if (selected.isEmpty()) return;

// 只复制第一个选中的项目
HmiComponent* itemToCopy = qgraphicsitem_cast<HmiComponent*>(selected.first());
if (!itemToCopy) return;

// 存储组件信息到 "剪贴板"
if (dynamic_cast<HmiButton*>(itemToCopy)) {
m_copiedType = ComponentType::Button;
} else if (dynamic_cast<HmiIndicator*>(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<QGraphicsItem*> 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);
}
}

+ 10
- 11
hmimodule.h Vedi File

@@ -3,8 +3,8 @@

#include <QObject>
#include "ui_MainWindow.h"
// #include "customgraphics.h" // 已被 customgraphicsscene.h 包含
#include "customgraphicsscene.h" // 引入新的场景头文件
#include "customgraphicsscene.h"
#include <QList> // 引入 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<int> m_availablePageNumbers; // 用于存储可用的页面编号 (有序列表)
};

#endif // HMIMODULE_H

Caricamento…
Annulla
Salva