Ver código fonte

实现HMI的图像化编程,缩放,移动,复制粘贴删除功能

main
email 4 dias atrás
pai
commit
0d11c81369
14 arquivos alterados com 383 adições e 149 exclusões
  1. +4
    -1
      IntegratedPlatform/IntegratedPlatform.pro
  2. +1
    -1
      IntegratedPlatform/IntegratedPlatform.pro.user
  3. +55
    -59
      IntegratedPlatform/hmiwidget.cpp
  4. +26
    -35
      IntegratedPlatform/hmiwidget.h
  5. BIN
      IntegratedPlatform/images/T-常开触点-01.png
  6. BIN
      IntegratedPlatform/images/T-常闭触点-01-01.png
  7. BIN
      IntegratedPlatform/images/大于等于.png
  8. BIN
      IntegratedPlatform/images/按钮.png
  9. BIN
      IntegratedPlatform/images/灯泡.png
  10. BIN
      IntegratedPlatform/images/线-圈-圈.png
  11. +2
    -0
      IntegratedPlatform/main.cpp
  12. +271
    -44
      IntegratedPlatform/mainwindow.cpp
  13. +10
    -1
      IntegratedPlatform/mainwindow.h
  14. +14
    -8
      IntegratedPlatform/mainwindow.ui

+ 4
- 1
IntegratedPlatform/IntegratedPlatform.pro Ver arquivo

@@ -32,4 +32,7 @@ qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

DISTFILES +=
DISTFILES += \
images/T-常开触点-01.png \
images/按钮.png \
images/灯泡.png

+ 1
- 1
IntegratedPlatform/IntegratedPlatform.pro.user Ver arquivo

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.11.1, 2025-08-05T21:07:14. -->
<!-- Written by QtCreator 4.11.1, 2025-08-06T20:14:02. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>


+ 55
- 59
IntegratedPlatform/hmiwidget.cpp Ver arquivo

@@ -1,90 +1,86 @@
#include "hmiwidget.h"
#include <QGraphicsSceneMouseEvent>
#include <QCursor>
#include <QDebug>
#include<QMenu>
#include<QGraphicsScene>
// ResizableShape 模板类的实现
template <typename BaseShape>
ResizableShape<BaseShape>::ResizableShape(qreal x, qreal y, qreal w, qreal h)
: BaseShape(x, y, w, h), resizing(false)
{
this->setFlag(QGraphicsItem::ItemIsMovable, true);
this->setFlag(QGraphicsItem::ItemIsSelectable, true);
this->setAcceptHoverEvents(true);
}

ResizableRectangle::ResizableRectangle(qreal x, qreal y, qreal w, qreal h)
: QGraphicsRectItem(x, y, w, h), resizing(false)
template <typename BaseShape>
void ResizableShape<BaseShape>::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
if (isInResizeArea(event->pos())) {
this->setCursor(Qt::SizeFDiagCursor);
} else {
this->setCursor(Qt::SizeAllCursor);
}
BaseShape::hoverMoveEvent(event);
}

template <typename BaseShape>
bool ResizableShape<BaseShape>::isInResizeArea(const QPointF &pos) const
{
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setCursor(Qt::ArrowCursor);
QRectF r = this->rect();
QRectF resizeArea(r.bottomRight() - QPointF(20, 20), r.bottomRight());
return resizeArea.contains(pos);
}

void ResizableRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event)
template <typename BaseShape>
void ResizableShape<BaseShape>::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
// 检查是否在调整区域
if (rect().bottomRight().x() - 10 <= event->pos().x() &&
rect().bottomRight().y() - 10 <= event->pos().y()) {
if (isInResizeArea(event->pos())) {
resizing = true;
setCursor(Qt::SizeFDiagCursor);
this->setCursor(Qt::SizeFDiagCursor);
} else {
// 传递事件给基类处理移动
resizing = false;
setCursor(Qt::SizeAllCursor);
QGraphicsRectItem::mousePressEvent(event);
this->setCursor(Qt::SizeAllCursor);
BaseShape::mousePressEvent(event);
}
}

void ResizableRectangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
template <typename BaseShape>
void ResizableShape<BaseShape>::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (resizing) {
// 调整大小逻辑
QRectF newRect = rect();
QRectF newRect = this->rect();
newRect.setBottomRight(event->pos());
setRect(newRect);
this->setRect(newRect);
} else {
// 传递事件给基类处理移动
QGraphicsRectItem::mouseMoveEvent(event);
BaseShape::mouseMoveEvent(event);
}
}

void ResizableRectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
template <typename BaseShape>
void ResizableShape<BaseShape>::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
resizing = false;
setCursor(Qt::ArrowCursor);
QGraphicsRectItem::mouseReleaseEvent(event);
this->setCursor(Qt::SizeAllCursor);
BaseShape::mouseReleaseEvent(event);
}

// -------------------- ResizableEllipse --------------------

ResizableEllipse::ResizableEllipse(qreal x, qreal y, qreal w, qreal h)
: QGraphicsEllipseItem(x, y, w, h), resizing2(false)
template <typename BaseShape>//虚函数
void ResizableShape<BaseShape>::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setCursor(Qt::ArrowCursor);
BaseShape::paint(painter, option, widget);
}

void ResizableEllipse::mousePressEvent(QGraphicsSceneMouseEvent *event)
// ResizableRectangle 实现
ResizableRectangle::ResizableRectangle(qreal x, qreal y, qreal w, qreal h)
: ResizableShape<QGraphicsRectItem>(x, y, w, h)
{
QRectF ellipseRect = rect();
if (ellipseRect.bottomRight().x() - 10 <= event->pos().x() &&
ellipseRect.bottomRight().y() - 10 <= event->pos().y()) {
resizing2 = true;
setCursor(Qt::SizeFDiagCursor);
} else {
// 传递事件给基类处理移动
resizing2 = false;
setCursor(Qt::SizeAllCursor);
QGraphicsEllipseItem::mousePressEvent(event);
}
}

void ResizableEllipse::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
// ResizableEllipse 实现
ResizableEllipse::ResizableEllipse(qreal x, qreal y, qreal w, qreal h)
: ResizableShape<QGraphicsEllipseItem>(x, y, w, h)
{
if (resizing2) {
QRectF newRect = rect();
newRect.setBottomRight(event->pos());
setRect(newRect);
} else {
// 传递事件给基类处理移动
QGraphicsEllipseItem::mouseMoveEvent(event);
}
}

void ResizableEllipse::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
resizing2 = false;
setCursor(Qt::ArrowCursor);
QGraphicsEllipseItem::mouseReleaseEvent(event);
}
// 显式实例化模板类
template class ResizableShape<QGraphicsRectItem>;
template class ResizableShape<QGraphicsEllipseItem>;

+ 26
- 35
IntegratedPlatform/hmiwidget.h Ver arquivo

@@ -1,50 +1,41 @@
#ifndef HMIELEMENT_H
#define HMIELEMENT_H
#ifndef HMIWIDGET_H
#define HMIWIDGET_H

#include <QGraphicsRectItem>
#include <QGraphicsEllipseItem>
#include <QGraphicsSceneMouseEvent>
#include <QPen>
#include <QBrush>
#include <QCursor>
#include <QPainter>

// 可调整大小的形状模板基类
template <typename BaseShape>
class ResizableShape : public BaseShape {
protected:
bool resizing;

// 自定义矩形类,支持大小调整
class ResizableRectangle : public QGraphicsRectItem
{
public:
// 构造函数
ResizableRectangle(qreal x, qreal y, qreal w, qreal h);
ResizableShape(qreal x, qreal y, qreal w, qreal h);

protected:
// 鼠标按下事件
// 事件处理
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;

// 鼠标移动事件
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;

// 鼠标释放事件
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
protected:
bool isInResizeArea(const QPointF &pos) const;
};

private:
bool resizing; //是否正在调整大小
// 可调整大小的矩形
class ResizableRectangle : public ResizableShape<QGraphicsRectItem> {
public:
ResizableRectangle(qreal x, qreal y, qreal w, qreal h);
};

// 自定义圆形类,支持大小调整
class ResizableEllipse : public QGraphicsEllipseItem
{
// 可调整大小的椭圆
class ResizableEllipse : public ResizableShape<QGraphicsEllipseItem> {
public:
// 构造函数
ResizableEllipse(qreal x, qreal y, qreal w, qreal h);

protected:
// 鼠标按下事件
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;

// 鼠标移动事件
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;

// 鼠标释放事件
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;

private:
bool resizing2; // 是否正在调整大小
};
#endif // HMIELEMENT_H

#endif // HMIWIDGET_H

BIN
IntegratedPlatform/images/T-常开触点-01.png Ver arquivo

Antes Depois
Largura: 200  |  Altura: 200  |  Tamanho: 1.4 KiB

BIN
IntegratedPlatform/images/T-常闭触点-01-01.png Ver arquivo

Antes Depois
Largura: 200  |  Altura: 200  |  Tamanho: 5.2 KiB

BIN
IntegratedPlatform/images/大于等于.png Ver arquivo

Antes Depois
Largura: 200  |  Altura: 200  |  Tamanho: 5.8 KiB

BIN
IntegratedPlatform/images/按钮.png Ver arquivo

Antes Depois
Largura: 200  |  Altura: 200  |  Tamanho: 4.1 KiB

BIN
IntegratedPlatform/images/灯泡.png Ver arquivo

Antes Depois
Largura: 200  |  Altura: 200  |  Tamanho: 8.4 KiB

BIN
IntegratedPlatform/images/线-圈-圈.png Ver arquivo

Antes Depois
Largura: 200  |  Altura: 200  |  Tamanho: 7.4 KiB

+ 2
- 0
IntegratedPlatform/main.cpp Ver arquivo

@@ -2,6 +2,7 @@

#include <QApplication>
#include<QStyleFactory>
#include<QDir>
int main(int argc, char *argv[])
{
QApplication::setStyle(QStyleFactory::create("Fusion"));
@@ -9,4 +10,5 @@ int main(int argc, char *argv[])
MainWindow w;
w.show();
return a.exec();

}

+ 271
- 44
IntegratedPlatform/mainwindow.cpp Ver arquivo

@@ -1,23 +1,47 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"hmiwidget.h"

#include<QDebug>
#include<QDir>
#include <QGraphicsView>
#include <QGraphicsScene>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
,canDrawCircle(false)
,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);
ui-> graphicsView_2->viewport()->installEventFilter(this);
connect(ui->actiondelete, &QAction::triggered, this, &MainWindow::onActionDeleteTriggered);
connect(ui->actioncopy, &QAction::triggered, this, &MainWindow::onActionCopyTriggered);
connect(ui->actionpaste, &QAction::triggered, this, &MainWindow::onActionPasteTriggered);

addDockWidget(Qt::BottomDockWidgetArea, ui->dockWidget_3);//将dockWidget_3添加到主窗口的下方
ui->treeWidget_2->topLevelItem(0)->setIcon(0, QIcon("C:/Users/admin/Desktop/灯泡.png"));
ui->treeWidget_2->topLevelItem(1)->setIcon(0, QIcon("C:/Users/admin/Desktop/按钮.png"));
}

MainWindow::~MainWindow()
@@ -29,58 +53,261 @@ void MainWindow::onHmiItemClicked(QTreeWidgetItem *item)
{
if (item->text(0) == "指示灯")
{
canDrawCircle = true;
canDrawEllipse = true;
canDrawRectangle = false;
}
else if(item->text(0) == "按钮")
else if (item->text(0) == "按钮")
{
canDrawCircle=false;
canDrawRectangle = true;//如果点击的是按钮,则不允许绘制灯
canDrawEllipse = false;
canDrawRectangle = true;
}
else {
canDrawRectangle = false;//如果点击的是灯,则不允许绘制按钮
canDrawCircle = false;
else
{
canDrawEllipse = false;
canDrawRectangle = false;
}
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
// 修正1:使用一致的视图对象名(graphicsView_2)
if (obj != ui->graphicsView_2->viewport()) {
return false; // 不是我们关心的对象,不处理
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::LeftButton) {
// 获取点击的场景坐标
if (event->type() == QEvent::MouseButtonPress)//点击生成
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::RightButton)//打开右键菜单
{
QPointF scenePos = ui->graphicsView_2->mapToScene(mouseEvent->pos());

// 根据标志绘制元素
if (canDrawCircle) {
ResizableEllipse *circle = new ResizableEllipse(
scenePos.x(), scenePos.y(), 50, 50);
circle->setBrush(QBrush(Qt::red)); // 设置指示灯颜色
scene->addItem(circle);
QGraphicsItem *item = scene->itemAt(scenePos, ui->graphicsView_2->transform());
if (item && !item->isSelected())// 如果有项在点击位置,选中它并清除其他选择
{
scene->clearSelection(); // 清除所有当前选择
item->setSelected(true); // 选中当前项
}
else if (canDrawRectangle) {
ResizableRectangle *rectangle = new ResizableRectangle(
scenePos.x(), scenePos.y(), 100, 50);
rectangle->setBrush(QBrush(Qt::yellow)); // 设置按钮颜色
scene->addItem(rectangle);
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);
}

// 重置绘制标志
canDrawCircle = false;
canDrawRectangle = false;

// 修正2:使用一致的树控件对象名(treeWidget_2)
if (ui->treeWidget_2->currentItem()) {
ui->treeWidget_2->currentItem()->setSelected(false);
if (canDrawEllipse)
{
createEllipse(scenePos); // 封装为函数,避免重复代码
resetDrawFlags();
}

return true; // 事件已处理
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;
}
// 修正3:正确处理未过滤的事件
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::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));
}

+ 10
- 1
IntegratedPlatform/mainwindow.h Ver arquivo

@@ -19,12 +19,21 @@ public:
~MainWindow();
private slots:
void onHmiItemClicked(QTreeWidgetItem *item);
void onActionDeleteTriggered(); // 添加删除功能的槽函数
void onActionCopyTriggered();//复制功能槽函数
void onActionPasteTriggered();//粘贴功能槽函数
void createEllipse(const QPointF &pos); // 创建指示灯(圆形)
void createRectangle(const QPointF &pos); // 创建按钮(矩形)
void resetDrawFlags(); // 重置绘制标志
void showContextMenu(QPoint pos);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
Ui::MainWindow *ui;
bool canDrawCircle;
bool canDrawEllipse;
bool canDrawRectangle;
QGraphicsScene *scene; // QGraphicsScene,用于容纳图形项
QList<QByteArray> copiedItemsData; // 存储序列化的图形项数据
QPointF lastPastePos; // 记录上次粘贴位置
};
#endif // MAINWINDOW_H

+ 14
- 8
IntegratedPlatform/mainwindow.ui Ver arquivo

@@ -52,7 +52,7 @@
<property name="font">
<font>
<family>宋体</family>
<pointsize>16</pointsize>
<pointsize>18</pointsize>
</font>
</property>
<column>
@@ -103,6 +103,9 @@
<property name="mouseTracking">
<bool>false</bool>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
</widget>
</item>
<item row="0" column="0">
@@ -110,12 +113,15 @@
<property name="font">
<font>
<family>宋体</family>
<pointsize>16</pointsize>
<pointsize>18</pointsize>
</font>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="textElideMode">
<enum>Qt::ElideMiddle</enum>
</property>
<column>
<property name="text">
<string>控件栏</string>
@@ -175,9 +181,9 @@
<property name="title">
<string>操作</string>
</property>
<addaction name="actionxioam"/>
<addaction name="actionzhantuie"/>
<addaction name="actionshanchu"/>
<addaction name="actioncopy"/>
<addaction name="actionpaste"/>
<addaction name="actiondelete"/>
</widget>
<widget class="QMenu" name="menu_3">
<property name="font">
@@ -240,7 +246,7 @@
</font>
</property>
</action>
<action name="actionxioam">
<action name="actioncopy">
<property name="text">
<string>复制</string>
</property>
@@ -284,7 +290,7 @@
</font>
</property>
</action>
<action name="actionzhantuie">
<action name="actionpaste">
<property name="text">
<string>粘贴</string>
</property>
@@ -295,7 +301,7 @@
</font>
</property>
</action>
<action name="actionshanchu">
<action name="actiondelete">
<property name="text">
<string>删除</string>
</property>


Carregando…
Cancelar
Salvar