#include "mainwindow.h" #include "ui_mainwindow.h" #include"hmiwidget.h" #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) ,canDrawEllipse(false) ,canDrawRectangle(false) { ui->setupUi(this); addDockWidget(Qt::BottomDockWidgetArea, ui->dockWidget_3);//将dockWidget_3添加到主窗口的下方 scene = new QGraphicsScene(this); scene->setSceneRect(0, 0, 800, 600);//因为场景初始无内容时,QGraphicsView 自动将场景中心与视图中心对齐 scene->setBackgroundBrush(QBrush(Qt::lightGray)); ui->graphicsView_2->setScene(scene); ui->graphicsView_2->setRenderHint(QPainter::Antialiasing); ui->graphicsView_2->setDragMode(QGraphicsView::RubberBandDrag); ui->graphicsView_2->setAcceptDrops(true);// 启用视图的拖放功能(接收拖拽) ui->graphicsView_2->viewport()->installEventFilter(this); ui->treeWidget_2->setDragEnabled(true);// 允许拖拽 ui->treeWidget_2->setDragDropMode(QAbstractItemView::DragOnly);// 仅拖拽 ui->actiondelete->setShortcut(QKeySequence::Delete);//设置快捷键 ui->actioncopy->setShortcut(QKeySequence::Copy); ui->actionpaste->setShortcut(QKeySequence::Paste); ui->treeWidget->topLevelItem(0)->setIcon(0, QIcon("../two/IntegratedPlatform/images/T-常开触点-01.png")); ui->treeWidget->topLevelItem(1)->setIcon(0, QIcon("../two/IntegratedPlatform/images/T-常闭触点-01-01.png")); ui->treeWidget->topLevelItem(2)->setIcon(0, QIcon("../two/IntegratedPlatform/images/大于等于.png")); ui->treeWidget->topLevelItem(3)->setIcon(0, QIcon("../two/IntegratedPlatform/images/线-圈-圈.png")); ui->treeWidget_2->topLevelItem(0)->setIcon(0, QIcon("../two/IntegratedPlatform/images/灯泡.png")); ui->treeWidget_2->topLevelItem(1)->setIcon(0, QIcon("../two/IntegratedPlatform/images/按钮.png")); connect(ui->treeWidget_2, &QTreeWidget::itemClicked, this, &MainWindow::onHmiItemClicked); connect(ui->actiondelete, &QAction::triggered, this, &MainWindow::onActionDeleteTriggered); connect(ui->actioncopy, &QAction::triggered, this, &MainWindow::onActionCopyTriggered); connect(ui->actionpaste, &QAction::triggered, this, &MainWindow::onActionPasteTriggered); } MainWindow::~MainWindow() { delete ui; } void MainWindow::onHmiItemClicked(QTreeWidgetItem *item) { if (item->text(0) == "指示灯") { canDrawEllipse = true; canDrawRectangle = false; } else if (item->text(0) == "按钮") { canDrawEllipse = false; canDrawRectangle = true; } else { canDrawEllipse = false; canDrawRectangle = false; } } bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if (obj != ui->graphicsView_2->viewport()) { return QMainWindow::eventFilter(obj, event); } if (event->type() == QEvent::MouseButtonPress)//点击生成 { QMouseEvent *mouseEvent = static_cast(event); if (mouseEvent->button() == Qt::RightButton)//打开右键菜单 { QPointF scenePos = ui->graphicsView_2->mapToScene(mouseEvent->pos()); QGraphicsItem *item = scene->itemAt(scenePos, ui->graphicsView_2->transform()); if (item && !item->isSelected())// 如果有项在点击位置,选中它并清除其他选择 { scene->clearSelection(); // 清除所有当前选择 item->setSelected(true); // 选中当前项 } QPoint globalPos = mouseEvent->globalPos(); showContextMenu(globalPos); return true; } if (mouseEvent->button() == Qt::LeftButton) { QPointF scenePos = ui->graphicsView_2->mapToScene(mouseEvent->pos()); QGraphicsItem *item = scene->itemAt(scenePos, ui->graphicsView_2->transform()); if (item) { return QMainWindow::eventFilter(obj, event); } if (canDrawEllipse) { createEllipse(scenePos); // 封装为函数,避免重复代码 resetDrawFlags(); } else if (canDrawRectangle) { createRectangle(scenePos); // 封装为函数 resetDrawFlags(); } if (!item) { scene->clearSelection(); if (ui->treeWidget_2->currentItem()) { ui->treeWidget_2->currentItem()->setSelected(false); } } return true; } } //拖拽生成 if (event->type() == QEvent::DragEnter) { QDragEnterEvent *dragEvent = static_cast(event); if (dragEvent->source() == ui->treeWidget_2)//检查拖拽源是否为树控件,并接受拖拽 { dragEvent->acceptProposedAction(); return true; } } // 拖拽移动(可选:显示拖拽反馈) if (event->type() == QEvent::DragMove) { QDragMoveEvent *dragEvent = static_cast(event); dragEvent->acceptProposedAction(); return true; } // 拖拽释放(生成图形) if (event->type() == QEvent::Drop) { QDropEvent *dropEvent = static_cast(event); QModelIndex index = ui->treeWidget_2->currentIndex();// 获取拖拽的树项 if (!index.isValid()) return true; QTreeWidgetItem *item = ui->treeWidget_2->currentItem(); if (!item) return true; QPointF scenePos = ui->graphicsView_2->mapToScene(dropEvent->pos());// 计算释放位置(转换为场景坐标) if (item->text(0) == "指示灯") { createEllipse(scenePos); } else if (item->text(0) == "按钮") { createRectangle(scenePos); } dropEvent->acceptProposedAction(); return true; } return QMainWindow::eventFilter(obj, event); } //删除 void MainWindow::onActionDeleteTriggered() { QList selectedItems = scene->selectedItems();//获取场景中所有选中的项 foreach (QGraphicsItem *item, selectedItems)//遍历并删除所有选中的项 { scene->removeItem(item); delete item;//删除对象 } } // 复制功能 void MainWindow::onActionCopyTriggered() { copiedItemsData.clear(); QList selectedItems = scene->selectedItems(); if (selectedItems.isEmpty()) return; foreach (QGraphicsItem *item, selectedItems) { QByteArray itemData; QDataStream stream(&itemData, QIODevice::WriteOnly); stream << item->type();// 基础属性 stream << item->pos(); stream << item->flags(); stream << item->transform(); stream << item->isVisible(); if (auto shapeItem = dynamic_cast(item))//处理所有图形形状项 { stream << shapeItem->pen(); stream << shapeItem->brush(); stream << shapeItem->boundingRect(); } if (auto resizableRect = dynamic_cast(item))//处理矩形圆形两项,存储几何信息 { stream << resizableRect->rect();//实际存储的矩形 } else if (auto resizableEllipse = dynamic_cast(item)) { stream << resizableEllipse->rect(); } copiedItemsData.append(itemData); } lastPastePos = selectedItems.first()->pos(); } // 粘贴功能 void MainWindow::onActionPasteTriggered() { if (copiedItemsData.isEmpty()) return; QPointF offset(20,20); lastPastePos+=offset; scene->clearSelection(); foreach (const QByteArray &itemData, copiedItemsData) { QDataStream stream(itemData); int itemType; QPointF pos; QGraphicsItem::GraphicsItemFlags flags; QTransform transform; bool visible; stream >> itemType >> pos >> flags >> transform >> visible; QGraphicsItem *newItem = nullptr; switch (itemType) { case QGraphicsRectItem::Type: { QPen pen; QBrush brush; QRectF rect; stream >> pen >> brush >> rect; ResizableRectangle *rectItem = new ResizableRectangle(rect.x(), rect.y(), rect.width(), rect.height()); rectItem->setPen(pen); rectItem->setBrush(brush); newItem = rectItem; break; } case QGraphicsEllipseItem::Type: { QPen pen; QBrush brush; QRectF rect; stream >> pen >> brush >> rect; ResizableEllipse *ellipseItem = new ResizableEllipse(rect.x(), rect.y(), rect.width(), rect.height()); ellipseItem->setPen(pen); ellipseItem->setBrush(brush); newItem = ellipseItem; break; } } if (newItem) { scene->addItem(newItem); newItem->setPos(lastPastePos); newItem->setFlags(flags); newItem->setTransform(transform); newItem->setVisible(visible); newItem->setSelected(true); } } } void MainWindow::createEllipse(const QPointF &pos) { ResizableEllipse *ellipse = new ResizableEllipse(pos.x(), pos.y(), 50, 50); ellipse->setBrush(QBrush(Qt::red)); ellipse->setPen(QPen(Qt::black, 1)); scene->addItem(ellipse); ellipse->setSelected(true); } void MainWindow::createRectangle(const QPointF &pos) { ResizableRectangle *rectangle = new ResizableRectangle(pos.x(), pos.y(), 100, 50); rectangle->setBrush(QBrush(Qt::yellow)); rectangle->setPen(QPen(Qt::black, 1)); scene->addItem(rectangle); rectangle->setSelected(true); } void MainWindow::resetDrawFlags() { canDrawEllipse = false; canDrawRectangle = false; if (ui->treeWidget_2->currentItem()) { ui->treeWidget_2->currentItem()->setSelected(false); } } void MainWindow::showContextMenu(QPoint pos) { QPoint viewportPos = ui->graphicsView_2->mapFromGlobal(pos); QPointF scenePos = ui->graphicsView_2->mapToScene(viewportPos); QGraphicsItem* clickedItem = scene->itemAt(scenePos, ui->graphicsView_2->transform());//检查是否有图形项在点击位置 QMenu contextMenu(this); if (!clickedItem) { QAction* pasteAction = contextMenu.addAction("粘贴");// 空白处右键:只添加粘贴选项 pasteAction->setEnabled(!copiedItemsData.isEmpty()); connect(pasteAction, &QAction::triggered, this, &MainWindow::onActionPasteTriggered); contextMenu.exec(pos+QPoint(10, 10)); return; } // 添加动作 QAction* propertiesAction = contextMenu.addAction("属性"); QAction* copyAction = contextMenu.addAction("复制"); QAction* pasteAction = contextMenu.addAction("粘贴"); QAction* deleteAction = contextMenu.addAction("删除"); QAction* onAction = contextMenu.addAction("置为ON"); QAction* offAction = contextMenu.addAction("置为OFF"); // 连接动作到现有功能 connect(deleteAction, &QAction::triggered, this, &MainWindow::onActionDeleteTriggered); connect(copyAction, &QAction::triggered, this, &MainWindow::onActionCopyTriggered); connect(pasteAction, &QAction::triggered, this, &MainWindow::onActionPasteTriggered); contextMenu.exec(pos+QPoint(10, 10)); }