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();
}


