综合平台编辑器
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

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