|
- #include "customgraphicsscene.h"
- #include <QGraphicsSceneMouseEvent>
- #include <QGraphicsView>
- #include <QKeyEvent>
- #include <QGuiApplication>
- #include <QMenu>
-
- // 实现新的构造函数
- 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);
- }
- }
|