#include "customgraphicsscene.h" #include #include #include #include #include // 实现新的构造函数 CustomGraphicsScene::CustomGraphicsScene(QGraphicsView* view, QObject *parent) : QGraphicsScene(parent), m_mode(Normal), m_view(view) { // 断言确保传入的 view 是有效的 Q_ASSERT(m_view); } void CustomGraphicsScene::setMode(Mode mode) { if (m_mode == mode) return; m_mode = mode; // 根据模式设置光标 if (m_mode == CreateItem) { m_view->setCursor(Qt::CrossCursor); } else { m_view->setCursor(Qt::ArrowCursor); // 恢复为标准箭头光标 } } void CustomGraphicsScene::setComponentTypeToCreate(ComponentType type) { m_componentTypeToCreate = type; } void CustomGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (mouseEvent->button() != Qt::LeftButton) { QGraphicsScene::mousePressEvent(mouseEvent); return; } if (m_mode == CreateItem) { HmiComponent* item = nullptr; switch (m_componentTypeToCreate) { case ComponentType::Button: item = new HmiButton(); break; case ComponentType::Indicator: item = new HmiIndicator(); break; } if (item) { item->setPos(mouseEvent->scenePos()); if (item->scene() == nullptr) { addItem(item); emit componentCreated(item); } else { // 如果 item 已经被添加到场景中,则删除它,避免内存泄漏 delete item; } } setMode(Normal); } else { QGraphicsScene::mousePressEvent(mouseEvent); } } void CustomGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { QGraphicsScene::mouseMoveEvent(mouseEvent); } void CustomGraphicsScene::keyPressEvent(QKeyEvent *keyEvent) { // 退出创建模式 if (keyEvent->key() == Qt::Key_Escape && m_mode == CreateItem) { setMode(Normal); keyEvent->accept(); return; } // 处理删除、复制、粘贴 if (selectedItems().isEmpty()) { QGraphicsScene::keyPressEvent(keyEvent); return; } switch (keyEvent->key()) { case Qt::Key_Delete: emit deleteRequestFromScene(); keyEvent->accept(); break; case Qt::Key_C: if (keyEvent->modifiers() & Qt::ControlModifier) { emit copyRequestFromScene(); keyEvent->accept(); } break; case Qt::Key_V: if (keyEvent->modifiers() & Qt::ControlModifier) { // 使用与 contextMenuEvent 相同的方式获取粘贴位置 QPointF pastePos = views().first()->mapToScene(views().first()->viewport()->mapFromGlobal(QCursor::pos())); emit pasteRequestFromScene(pastePos); keyEvent->accept(); } break; default: break; } QGraphicsScene::keyPressEvent(keyEvent); } void CustomGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent) { // 检查鼠标下方是否有图形项 QGraphicsItem *item = itemAt(contextMenuEvent->scenePos(), views().first()->transform()); if (!item) { // 如果点击在空白处,则显示我们的粘贴菜单 contextMenuEvent->accept(); QMenu menu; QAction *pasteAction = menu.addAction("粘贴"); // 将菜单动作连接到场景的粘贴请求信号 connect(pasteAction, &QAction::triggered, this, [this, contextMenuEvent]() { emit pasteRequestFromScene(contextMenuEvent->scenePos()); }); menu.exec(contextMenuEvent->screenPos()); } else { // 如果点击在图形项上,则将事件传递给该图形项处理(这会调用 HmiComponent::contextMenuEvent) QGraphicsScene::contextMenuEvent(contextMenuEvent); } }