QGraphicsView 实现 简单工作流
一、运行效果
执行删除
二、简单介绍
使用scene和vie来完成最终显示。
// 创建 WorkflowScene 和视图 m_scene = new WorkFolwScene(); m_scene->setBackgroundBrush(Qt::black); m_view = new QGraphicsView(m_scene); m_view->setScene(m_scene);
绘制时当为空,只绘制矩形和文本。否则就绘制直线,三角形,矩形,文本。并且没绘制依次更新nextItemPos的位置。我这因为矩形宽100,三角形占据的水平位置差不多为10,所以每次给它加110就可以了,视觉效果还可以。
删除,当有两个以上,就倒着删除直线,三角形,矩形,文本。
三,代码
#ifndef WORKFOLWSCENE_H #define WORKFOLWSCENE_H #include<QGraphicsItem> #include<QGraphicsScene> #include<QWidget> #include<QMouseEvent> #include<QDebug> #include<QRandomGenerator> #include<QGraphicsSceneMouseEvent> class WorkFolwScene : public QGraphicsScene { public: // WorkFolwScene(); WorkFolwScene(QObject *parent = nullptr); void drawRectangle(); void drawArrow(); void clearLastDrawnItem(); private: QPointF nextItemPos; // 下一个图形的位置 }; #endif // WORKFOLWSCENE_H
#include "workfolwscene.h" //WorkFolwScene::WorkFolwScene() //{ //} WorkFolwScene::WorkFolwScene(QObject *parent):QGraphicsScene(parent) { nextItemPos.setX(0); } void WorkFolwScene::drawRectangle() { qDebug()<<"drawRectangle"; if (this->items().size()==0){ nextItemPos.setX(0); } // 创建矩形图形项 QGraphicsRectItem *rect = new QGraphicsRectItem(QRectF(nextItemPos.x(), nextItemPos.y(), 100, 50)); rect->setBrush(Qt::blue); // 设置矩形的填充颜色 addItem(rect); // 添加文本 QGraphicsTextItem *textItem = new QGraphicsTextItem("Hello World!"); int randomInt = QRandomGenerator::global()->bounded(10); textItem->setPlainText(QString::number(randomInt)); QFont font("Arial", 10); // 设置字体和大小 textItem->setFont(font); textItem->setDefaultTextColor(Qt::white); // 设置文本颜色 QPointF textPos = QPointF(nextItemPos.x() + 10, nextItemPos.y() + 10); // 文本位置偏移量 textItem->setPos(textPos); addItem(textItem); // 更新下一个图形的位置 nextItemPos.setX(nextItemPos.x() + 110); // 假设间隔为 101 } void WorkFolwScene::drawArrow() { qDebug()<<"drawRectangle"; qreal arrowSize = 10; // 箭头大小 qreal offsetY = 25; // 向下偏移量 // 创建箭头的线段,向下偏移25个单位 QGraphicsLineItem *line = new QGraphicsLineItem(QLineF(nextItemPos.x(), nextItemPos.y()+offsetY, nextItemPos.x() + 100, nextItemPos.y() + offsetY)); line->setPen(QPen(Qt::white)); // 设置箭头线段的颜色和样式 addItem(line); // 创建箭头头部的三角形,向下偏移25个单位 QPolygonF arrowHead; arrowHead << QPointF(0, 0) << QPointF(-arrowSize, arrowSize/2) << QPointF(-arrowSize, -arrowSize/2); QGraphicsPolygonItem *arrow = new QGraphicsPolygonItem(arrowHead); arrow->setBrush(Qt::white); // 设置箭头头部的颜色 arrow->setPen(QPen(Qt::white)); // 设置箭头头部的边框颜色和样式 arrow->setPos(nextItemPos.x() + 100, nextItemPos.y() + offsetY); // 设置箭头头部的位置 addItem(arrow); // 更新下一个图形的位置 nextItemPos.setX(nextItemPos.x() + 110); // 假设间隔为 110 } void WorkFolwScene::clearLastDrawnItem() { QList<QGraphicsItem *> itemsList = items(Qt::AscendingOrder); // 获取场景中所有的图形项 // 如果场景中没有图形项,则重置 nextItemPos 并直接返回 if (itemsList.isEmpty()) { nextItemPos.setX(0); this->clear(); return; } // 定义要删除的图形项类型列表,按照绘制顺序从后往前删除 QList<int> typesToDelete = { QGraphicsTextItem::Type, QGraphicsRectItem::Type, QGraphicsPolygonItem::Type, QGraphicsLineItem::Type }; // 从后往前遍历要删除的类型 for (int type : typesToDelete) { // 找到符合当前类型的最后绘制的图形项 for (int i = itemsList.size() - 1; i >= 0; --i) { QGraphicsItem *item = itemsList[i]; if (item->type() == type) { removeItem(item); delete item; itemsList.removeAt(i); // 从列表中移除已删除的项 break; // 删除一个后退出循环 } } } }
#include "widget.h" #include<QHBoxLayout> #include<QPushButton> Widget::Widget(QWidget *parent) : QWidget(parent) { //主界面布局 QVBoxLayout *layout = new QVBoxLayout(this); //创建 WorkflowScene 的widget // QWidget *wfWidget=new QWidget(); // wfWidget->setStyleSheet("border:1px solid black"); QHBoxLayout *hb1=new QHBoxLayout(); // 创建 WorkflowScene 和视图 m_scene = new WorkFolwScene(); m_scene->setBackgroundBrush(Qt::black); m_view = new QGraphicsView(m_scene); m_view->setScene(m_scene); // 添加到布局 hb1->addWidget(m_view); QHBoxLayout *hb2=new QHBoxLayout(); // 创建按钮并添加到布局 QPushButton *button = new QPushButton("绘制", this); QPushButton *clearBtn = new QPushButton("清除", this); connect(button, &QPushButton::clicked, this, &Widget::onDrawClicked); connect(clearBtn,&QPushButton::clicked, this, &Widget::onClearClicked); hb2->addWidget(button); hb2->addWidget(clearBtn); hb2->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding)); layout->addLayout(hb1); layout->addLayout(hb2); this->setLayout(layout); this->resize(800,750); } Widget::~Widget() { } void Widget::onDrawClicked() { if(m_scene->items().isEmpty()) { m_scene->clear(); m_view->resetTransform(); m_view->centerOn(0,0); m_scene->drawRectangle(); }else { m_scene->drawArrow(); m_scene->drawRectangle(); } } void Widget::onClearClicked() { m_scene->clearLastDrawnItem(); }