#include "mainwindow.h" #include "ui_mainwindow.h" #include"hmiwidget.h" #include #include #include #include #include #include #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::onActionPropertiesTriggered() { QList selectedItems = scene->selectedItems(); if (selectedItems.isEmpty()) return; QGraphicsItem* selectedItem = selectedItems.first(); QDialog dialog(this);// 创建对话框 dialog.setWindowTitle("属性设置"); QFormLayout* formLayout = new QFormLayout(&dialog); QColor tempOnColor = Qt::green;//临时变量存储选择的颜色 QColor tempOffColor = Qt::red;//临时变量存储选择的颜色 QLineEdit* nameEdit = new QLineEdit(&dialog);//对象输入框 if (auto namedItem = dynamic_cast(selectedItem)) { nameEdit->setText(namedItem->name()); } // 开状态颜色选择 QPushButton* onColorBtn = new QPushButton("", &dialog); onColorBtn->setStyleSheet("background-color:" + tempOnColor.name());; connect(onColorBtn, &QPushButton::clicked, [&]() { QColor newColor = QColorDialog::getColor(tempOnColor, &dialog, "选择ON状态颜色"); tempOnColor = newColor; onColorBtn->setStyleSheet("background-color:" + tempOnColor.name());; }); // 关状态颜色选择 QPushButton* offColorBtn = new QPushButton("", &dialog); offColorBtn->setStyleSheet("background-color:"+tempOffColor.name()); connect(offColorBtn, &QPushButton::clicked, [&]() { QColor newColor = QColorDialog::getColor(tempOffColor, &dialog, "选择OFF状态颜色"); tempOffColor = newColor; offColorBtn->setStyleSheet("background-color:"+tempOffColor.name()); }); formLayout->addRow("对象:", nameEdit); formLayout->addRow("ON颜色:", onColorBtn); formLayout->addRow("OFF颜色:", offColorBtn); QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog); formLayout->addRow(buttonBox); connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); if (dialog.exec() == QDialog::Accepted)//显示对话框并应用更改 { QString newName = nameEdit->text();// 应用新属性到图形项 if (auto ellipse = dynamic_cast(selectedItem)) { ellipse->setOnColor(tempOnColor); ellipse->setOffColor(tempOffColor); ellipse->setName(newName); ellipse->setBrush(tempOnColor); // 应用开状态颜色 } else if (auto rect = dynamic_cast(selectedItem)) { rect->setPressedColor(tempOnColor); rect->setReleasedColor(tempOffColor); rect->setName(newName); rect->setBrush(tempOffColor); // 应用关状态颜色 } selectedItem->update(); } } 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"); pasteAction->setEnabled(!copiedItemsData.isEmpty()); // 连接动作到现有功能 connect(deleteAction, &QAction::triggered, this, &MainWindow::onActionDeleteTriggered); connect(copyAction, &QAction::triggered, this, &MainWindow::onActionCopyTriggered); connect(pasteAction, &QAction::triggered, this, &MainWindow::onActionPasteTriggered); connect(propertiesAction, &QAction::triggered, this, &MainWindow::onActionPropertiesTriggered); contextMenu.exec(pos+QPoint(10, 10)); }