Qt之使用GraphicsView框架实现思维导图功能

本文介绍如何利用Qt框架开发一款具备基础思维导图功能的应用。内容包括静态和动态展示方式,如读取本地数据、自由添加/删除节点、节点重命名等。此外,还展示了线条绘制的代码实现,支持圆角折线和圆滑曲线的切换,并提供动态编辑和修改操作。目前应用已支持XML数据的保存和读取,未来将增加更多样式和拓展功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简述

我们常见的思维导图类型XMind软件,功能十分强大,提供了各式各样的导图样式、形式,那我们可以用Qt实现思维导图的功能吗,答案肯定是可以的,用图说明。

1、静态方式

读取本地数据的方式进行展示。
在这里插入图片描述

2、优化

(1)增加选中效果
(2)优化连接线条
在这里插入图片描述

3、动态方式

(1)可自由添加/删除节点
(2)双击可重命名节点
(3)可折叠节点
(4)每层节点颜色可自定义
(5)支持xml格式数据的保存/读取(可拓展为其他格式或数据库)

在这里插入图片描述
在这里插入图片描述


更新

(1)增加圆角折现和圆滑曲线两种状态切换
(2)增加动态编辑和静态显示
(3)增加修改操作
在这里插入图片描述

更新 1.1

Item增加设置图片效果。
在这里插入图片描述
在这里插入图片描述


线条绘制Code

void LineTest::paintEvent(QPaintEvent *event)
{
	QPoint startPoint = m_startPoint;
	QPoint endPoint = m_endPoint;
	int hSpace = 15;
	int radius = 8;

	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing, true);
	painter.setPen(QPen(Qt::gray, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
	// 判断是上弧线还是下弧线;
	if (endPoint.y() < startPoint.y())
	{
		// 绘制横线;
		painter.drawLine(startPoint, startPoint + QPoint(hSpace, 0));

		// 绘制竖线;
		startPoint += QPoint(hSpace, 0);
		QPoint vTopPoint = QPoint(startPoint.x(), endPoint.y() + radius);
		painter.drawLine(startPoint, vTopPoint);

		// 绘制上弧线;
		startPoint = vTopPoint;
		QPoint hTopPoint = QPoint(startPoint.x() + radius, endPoint.y());

		QPainterPath path(startPoint);
		// 绘制贝塞尔三次曲线;
		QPointF c1 = QPointF(startPoint.x(), hTopPoint.y());
		QPointF c2 = QPointF(startPoint.x() + 2, hTopPoint.y() + 2);
		path.cubicTo(c2, c2, hTopPoint);
		painter.drawPath(path);
		
		// 绘制横线;
		startPoint = hTopPoint;
		painter.drawLine(startPoint, endPoint);
	}
	else if (endPoint.y() > startPoint.y())
	{
		// 绘制横线;
		painter.drawLine(startPoint, startPoint + QPoint(hSpace, 0));

		// 绘制竖线;
		startPoint += QPoint(hSpace, 0);
		QPoint vBottomPoint = QPoint(startPoint.x(), endPoint.y() - radius);
		painter.drawLine(startPoint, vBottomPoint);

		// 绘制下弧线;
		startPoint = vBottomPoint;
		QPoint hBottomPoint = QPoint(startPoint.x() + radius, endPoint.y());

		QPainterPath path(startPoint);
		// 绘制贝塞尔三次曲线;
		QPointF c1 = QPointF(startPoint.x() + 2, hBottomPoint.y() - 2);
		QPointF c2 = QPointF(startPoint.x() + 2, hBottomPoint.y() + 2);
		path.cubicTo(c1, c1, hBottomPoint);
		painter.drawPath(path);

		// 绘制横线;
		startPoint = hBottomPoint;
		painter.drawLine(startPoint, endPoint);
	}
	else
	{
		// 绘制直线;
		painter.drawLine(startPoint, endPoint);
	}
}

目前只实现了初步导图的基础功能,后续会增加更多的样式选择及拓展。

### 使用Qt实现思维导图功能 为了创建一个基于Qt的简单思维导图应用,可以采用`QWidget`作为基础组件,并利用`QGraphicsView`框架来处理图形项和场景管理。下面是一个简化版的例子,展示了如何构建基本界面并允许用户通过点击按钮添加节点。 #### 创建项目结构 首先初始化一个新的Qt Widgets应用程序,在`.pro`文件里加入必要的模块支持: ```qmake QT += core gui widgets graphicsview ``` 这确保了程序能够访问到用于绘制图形视图所需的功能[^1]。 #### 设计主窗口布局 定义`mainWindow.ui`中的UI元素,至少应包含两个部分:一个是用来放置新节点的空白区域;另一个则是操作控件区,比如增加子主题或改变当前选中项目的属性等。对于后者来说,可以通过设置多个`QPushButton`实例完成不同命令的选择[^4]。 #### 实现核心逻辑 接下来关注于具体业务流程的设计——即每当按下某个特定按键时触发相应事件处理器,从而实现在画布上新增连接线段或是圆形/矩形框表示的新想法分支等功能。这里给出了一段关于响应“新建根节点”的Python伪代码转换成C++后的版本: ```cpp // mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QGraphicsScene> // 导入绘图场景类 #include <QGraphicsEllipseItem> // 圆形物品 #include <QVector> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_addRootButton_clicked(); // 添加根节点槽函数 private: Ui::MainWindow *ui; QGraphicsScene* scene; // 定义场景对象指针 }; #endif // MAINWINDOW_H // mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); this->scene = new QGraphicsScene(this); // 初始化场景 ui->graphicsView->setScene(scene); // 设置给图形视窗关联此场景 connect(ui->addRootButton, SIGNAL(clicked()), SLOT(on_addRootButton_clicked())); // 连接信号与槽 } void MainWindow::on_addRootButton_clicked() { static int idCounter = 0; qreal x = (this->width() / 2) - 50 ; // 居中位置X坐标 qreal y = 50; // Y轴起始高度固定值 auto item = new QGraphicsEllipseItem(-50,-50,100,100); // 新建椭圆形状代表节点 QFont font("Arial", 16,QFont::Bold); item->setFont(font); item->setPos(x,y); QString text = QStringLiteral("Node %1").arg(++idCounter); item->setData(0,text); // 存储文本数据至item内部 item->setToolTip(text.toUtf8()); // 提供鼠标悬停提示信息 this->scene->addItem(item); // 把新的节点添加进场景内显示出来 } ``` 上述代码片段实现了当用户单击界面上名为`addRootButton`的按钮之后,会在中央偏上的地方生成一个带有编号标签的小球体作为初始中心点。随着更多次的操作重复执行相同动作,则可逐步建立起完整的树状关系网路。
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值