综合平台编辑器
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.

149 rindas
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. } else {
  63. QGraphicsScene::mousePressEvent(mouseEvent);
  64. }
  65. }
  66. // mouseMoveEvent 函数无需改动
  67. void CustomGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
  68. {
  69. QGraphicsScene::mouseMoveEvent(mouseEvent);
  70. }
  71. // 修改或新增 keyPressEvent
  72. void CustomGraphicsScene::keyPressEvent(QKeyEvent *keyEvent)
  73. {
  74. // 退出创建模式
  75. if (keyEvent->key() == Qt::Key_Escape && m_mode == CreateItem) {
  76. setMode(Normal);
  77. keyEvent->accept();
  78. return;
  79. }
  80. // 处理删除、复制、粘贴
  81. if (selectedItems().isEmpty()) {
  82. QGraphicsScene::keyPressEvent(keyEvent);
  83. return;
  84. }
  85. switch (keyEvent->key()) {
  86. case Qt::Key_Delete:
  87. emit deleteRequestFromScene();
  88. keyEvent->accept();
  89. break;
  90. case Qt::Key_C:
  91. if (keyEvent->modifiers() & Qt::ControlModifier) {
  92. emit copyRequestFromScene();
  93. keyEvent->accept();
  94. }
  95. break;
  96. case Qt::Key_V:
  97. if (keyEvent->modifiers() & Qt::ControlModifier) {
  98. // 获取最后一个鼠标事件的位置来确定粘贴位置
  99. emit pasteRequestFromScene(views().first()->mapToScene(views().first()->mapFromGlobal(QCursor::pos())));
  100. keyEvent->accept();
  101. }
  102. break;
  103. default:
  104. break;
  105. }
  106. QGraphicsScene::keyPressEvent(keyEvent);
  107. }
  108. void CustomGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent)
  109. {
  110. // 检查鼠标下方是否有图形项
  111. QGraphicsItem *item = itemAt(contextMenuEvent->scenePos(), views().first()->transform());
  112. if (!item) {
  113. // 如果点击在空白处,则显示我们的粘贴菜单
  114. contextMenuEvent->accept();
  115. QMenu menu;
  116. QAction *pasteAction = menu.addAction("粘贴");
  117. // 将菜单动作连接到场景的粘贴请求信号
  118. connect(pasteAction, &QAction::triggered, this, [this, contextMenuEvent]() {
  119. emit pasteRequestFromScene(contextMenuEvent->scenePos());
  120. });
  121. menu.exec(contextMenuEvent->screenPos());
  122. } else {
  123. // 如果点击在图形项上,则将事件传递给该图形项处理
  124. // (这会调用 HmiComponent::contextMenuEvent)
  125. QGraphicsScene::contextMenuEvent(contextMenuEvent);
  126. }
  127. }