|
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include"hmiwidget.h"
- #include<QDebug>
- #include<QDir>
- #include <QGraphicsView>
- #include <QGraphicsScene>
- #include <QPushButton>
- #include <QColorDialog>
- #include <QLineEdit>
- #include <QLabel>
- #include <QDialogButtonBox>
- #include <QFormLayout>
- 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<QMouseEvent*>(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<QDragEnterEvent*>(event);
- if (dragEvent->source() == ui->treeWidget_2)//检查拖拽源是否为树控件,并接受拖拽
- {
- dragEvent->acceptProposedAction();
- return true;
- }
- }
- // 拖拽移动(可选:显示拖拽反馈)
- if (event->type() == QEvent::DragMove)
- {
- QDragMoveEvent *dragEvent = static_cast<QDragMoveEvent*>(event);
- dragEvent->acceptProposedAction();
- return true;
- }
- // 拖拽释放(生成图形)
- if (event->type() == QEvent::Drop)
- {
- QDropEvent *dropEvent = static_cast<QDropEvent*>(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<QGraphicsItem*> selectedItems = scene->selectedItems();//获取场景中所有选中的项
- foreach (QGraphicsItem *item, selectedItems)//遍历并删除所有选中的项
- {
- scene->removeItem(item);
- delete item;//删除对象
- }
- }
- // 复制功能
- void MainWindow::onActionCopyTriggered()
- {
- copiedItemsData.clear();
- QList<QGraphicsItem*> 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<QAbstractGraphicsShapeItem*>(item))//处理所有图形形状项
- {
- stream << shapeItem->pen();
- stream << shapeItem->brush();
- stream << shapeItem->boundingRect();
- }
- if (auto resizableRect = dynamic_cast<ResizableRectangle*>(item))//处理矩形圆形两项,存储几何信息
- {
- stream << resizableRect->rect();//实际存储的矩形
- }
- else if (auto resizableEllipse = dynamic_cast<ResizableEllipse*>(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<QGraphicsItem*> 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<NamedItem*>(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<ResizableEllipse*>(selectedItem))
- {
- ellipse->setOnColor(tempOnColor);
- ellipse->setOffColor(tempOffColor);
- ellipse->setName(newName);
- ellipse->setBrush(tempOnColor); // 应用开状态颜色
- }
- else if (auto rect = dynamic_cast<ResizableRectangle*>(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));
- }
|