综合平台编辑器
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

138 строки
3.7 KiB

  1. #include "customgraphicsscene.h"
  2. #include <QGraphicsSceneMouseEvent>
  3. #include <QGraphicsView>
  4. #include <QKeyEvent>
  5. #include <QGuiApplication>
  6. #include <QMenu>
  7. // 实现新的构造函数
  8. CustomGraphicsScene::CustomGraphicsScene(QGraphicsView* view, QObject *parent)
  9. : QGraphicsScene(parent), m_mode(Normal), m_view(view)
  10. {
  11. // 断言确保传入的 view 是有效的
  12. Q_ASSERT(m_view);
  13. }
  14. void CustomGraphicsScene::setMode(Mode mode)
  15. {
  16. m_mode = mode;
  17. }
  18. void CustomGraphicsScene::setComponentTypeToCreate(ComponentType type)
  19. {
  20. m_componentTypeToCreate = type;
  21. }
  22. void CustomGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
  23. {
  24. if (mouseEvent->button() != Qt::LeftButton) {
  25. QGraphicsScene::mousePressEvent(mouseEvent);
  26. return;
  27. }
  28. if (m_mode == CreateItem) {
  29. HmiComponent* item = nullptr;
  30. switch (m_componentTypeToCreate) {
  31. case ComponentType::Button:
  32. item = new HmiButton();
  33. break;
  34. case ComponentType::Indicator:
  35. item = new HmiIndicator();
  36. break;
  37. }
  38. if (item)
  39. {
  40. item->setPos(mouseEvent->scenePos());
  41. if (item->scene() == nullptr)
  42. {
  43. addItem(item);
  44. emit componentCreated(item);
  45. }
  46. else
  47. {
  48. // 如果 item 已经被添加到场景中,则删除它,避免内存泄漏
  49. delete item;
  50. }
  51. }
  52. setMode(Normal);
  53. }
  54. else
  55. {
  56. QGraphicsScene::mousePressEvent(mouseEvent);
  57. }
  58. }
  59. void CustomGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
  60. {
  61. QGraphicsScene::mouseMoveEvent(mouseEvent);
  62. }
  63. void CustomGraphicsScene::keyPressEvent(QKeyEvent *keyEvent)
  64. {
  65. // 退出创建模式
  66. if (keyEvent->key() == Qt::Key_Escape && m_mode == CreateItem) {
  67. setMode(Normal);
  68. keyEvent->accept();
  69. return;
  70. }
  71. // 处理删除、复制、粘贴
  72. if (selectedItems().isEmpty()) {
  73. QGraphicsScene::keyPressEvent(keyEvent);
  74. return;
  75. }
  76. switch (keyEvent->key()) {
  77. case Qt::Key_Delete:
  78. emit deleteRequestFromScene();
  79. keyEvent->accept();
  80. break;
  81. case Qt::Key_C:
  82. if (keyEvent->modifiers() & Qt::ControlModifier) {
  83. emit copyRequestFromScene();
  84. keyEvent->accept();
  85. }
  86. break;
  87. case Qt::Key_V:
  88. if (keyEvent->modifiers() & Qt::ControlModifier) {
  89. // 使用与 contextMenuEvent 相同的方式获取粘贴位置
  90. QPointF pastePos = views().first()->mapToScene(views().first()->viewport()->mapFromGlobal(QCursor::pos()));
  91. emit pasteRequestFromScene(pastePos);
  92. keyEvent->accept();
  93. }
  94. break;
  95. default:
  96. break;
  97. }
  98. QGraphicsScene::keyPressEvent(keyEvent);
  99. }
  100. void CustomGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent)
  101. {
  102. // 检查鼠标下方是否有图形项
  103. QGraphicsItem *item = itemAt(contextMenuEvent->scenePos(), views().first()->transform());
  104. if (!item) {
  105. // 如果点击在空白处,则显示我们的粘贴菜单
  106. contextMenuEvent->accept();
  107. QMenu menu;
  108. QAction *pasteAction = menu.addAction("粘贴");
  109. // 将菜单动作连接到场景的粘贴请求信号
  110. connect(pasteAction, &QAction::triggered, this, [this, contextMenuEvent]() {
  111. emit pasteRequestFromScene(contextMenuEvent->scenePos());
  112. });
  113. menu.exec(contextMenuEvent->screenPos());
  114. } else {
  115. // 如果点击在图形项上,则将事件传递给该图形项处理(这会调用 HmiComponent::contextMenuEvent)
  116. QGraphicsScene::contextMenuEvent(contextMenuEvent);
  117. }
  118. }