Qt实现思维导图功能6『鹰眼视图』

这篇具有很好参考价值的文章主要介绍了Qt实现思维导图功能6『鹰眼视图』。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前文链接:Qt实现思维导图功能5『纵向分布模式』

百度网盘体验地址:
链接:https://pan.baidu.com/s/1xotlkSPfG7E_37y_XPfDng 
提取码:5li7

效果图
1、动态演示效果:

思维导图-鹰眼视图


2、静态展示图片:
Qt实现思维导图功能6『鹰眼视图』,项目,qt,开发语言

新增功能如下

序号 简述 具体功能
1 显示全场景 保持场景纵横比不变的情况下最大化显示全场景导图信息
1 矩形导航框 显示场景具体大小,随主视图缩放/移动而变化
1 视野跳转 鹰眼视图支持鼠标点击后立即跳转到指定位置,该位置将呈现在主视图视野中心
1 视野移动 鹰眼视图支持鼠标移动时触发主视图视野伴随移动,移动过程丝滑无卡顿

新增UI如下

序号 简述 具体功能
1 鹰眼视图窗口 显示和操控主视图中场景图元位置

核心代码文章来源地址https://www.toymoban.com/news/detail-578864.html

#pragma once

/*
 * 鹰眼视图窗口
 * 1、最大化显示全场景图元
 * 2、矩形导航框自适应场景缩放与移动
 */

#include <QWidget>
#include "ui_EagleWidget.h"

class QGraphicsView;
class QGraphicsPixmapItem;
class QGraphicsRectItem;

class EagleWidget : public QWidget
{
	Q_OBJECT

public:
	EagleWidget(QWidget *parent = nullptr);
	~EagleWidget();

	// 设置主视图
	void setMainView(QGraphicsView *view);

protected:
	bool eventFilter(QObject *watched, QEvent *event);

private slots:
	void on_btnClose_clicked();

private:
	Ui::EagleWidget ui;

	QGraphicsView *m_mainView;				// 主视图
	QGraphicsPixmapItem *m_bgPixmapItem;	// 背景图元
	QGraphicsRectItem *m_rectItem;			// 矩形导航框
};
#include "EagleWidget.h"
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QGraphicsRectItem>
#include <QMouseEvent>

EagleWidget::EagleWidget(QWidget *parent /*= nullptr*/)
	: QWidget(parent)
	, m_mainView(nullptr)
{
	ui.setupUi(this);
	setAttribute(Qt::WA_DeleteOnClose);
	m_bgPixmapItem = new QGraphicsPixmapItem();
	m_rectItem = new QGraphicsRectItem;
	m_rectItem->setPen(QPen(Qt::red));
	ui.graphicsView->setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing);
	ui.graphicsView->viewport()->installEventFilter(this);

	ui.graphicsView->setCursor(QCursor(Qt::CrossCursor));
}

EagleWidget::~EagleWidget()
{

}

void EagleWidget::setMainView(QGraphicsView *view)
{
	m_mainView = view;
	m_mainView->installEventFilter(this);
	m_mainView->viewport()->installEventFilter(this);

	QGraphicsScene *scene = new QGraphicsScene(ui.graphicsView->viewport()->rect());
	ui.graphicsView->setScene(scene);
	scene->setBackgroundBrush(m_mainView->scene()->backgroundBrush());
	scene->addItem(m_bgPixmapItem);
	scene->addItem(m_rectItem);
}

bool EagleWidget::eventFilter(QObject *watched, QEvent *event)
{
	if (m_mainView == nullptr)
		return QWidget::eventFilter(watched, event);

	if (watched == m_mainView)
	{
		if (event->type() == QEvent::Paint || event->type() == QEvent::Wheel)
		{		
			QGraphicsScene *scene = m_mainView->scene();
			// 设置图像大小与场景图元边界大小一致
			QRectF itemsBoundingRect = scene->itemsBoundingRect();
			QPixmap	pixmap(itemsBoundingRect.width(), itemsBoundingRect.height());
			// 渲染图像
			QPainter painter;
			painter.begin(&pixmap);
			painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing);
			scene->render(&painter, pixmap.rect(), itemsBoundingRect);
			painter.end();
			// 调整图像大小
			QSize eagleViewportSize = ui.graphicsView->viewport()->rect().size();
			QPixmap scaledPixmap = pixmap.scaled(eagleViewportSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
			m_bgPixmapItem->setPixmap(scaledPixmap);
			// 调整图像位置
			if (scaledPixmap.height() <= ui.graphicsView->viewport()->height())
				m_bgPixmapItem->setY((ui.graphicsView->viewport()->height() - scaledPixmap.height()) / 2.0);
			if (scaledPixmap.width() <= ui.graphicsView->viewport()->width())
				m_bgPixmapItem->setX((ui.graphicsView->viewport()->width() - scaledPixmap.width()) / 2.0);

			// 计算缩放后的图元大小与主视窗大小的水平/垂直比率
			QRectF bgPixmapRect = m_bgPixmapItem->boundingRect();
			QSize mainViewportSize = m_mainView->viewport()->rect().size();
			qreal scaleFactor = m_mainView->matrix().m11();
			double scaleH = itemsBoundingRect.width() * scaleFactor / mainViewportSize.width();
			double scaleV = itemsBoundingRect.height() * scaleFactor / mainViewportSize.height();
			double scaleMax = qMax(scaleH, scaleV);
			if (scaleMax <= 1)
			{// 当比率<=1时,矩形导航框为整个鹰眼视图中的背景图元大小
				m_rectItem->setRect(bgPixmapRect);
				m_rectItem->setPos(m_bgPixmapItem->pos());
			}
			else// scaleMax > 1
			{// 当比率>1时,矩形导航框为主视窗中图元占整个场景图元的比率所对应的鹰眼视图大小
				QPointF viewportTopLeftToScenePos = m_mainView->mapToScene(QPoint(0, 0));
				double offsetXRatio = (viewportTopLeftToScenePos.x() - itemsBoundingRect.x()) / itemsBoundingRect.width();
				double offsetYRatio = (viewportTopLeftToScenePos.y() - itemsBoundingRect.y()) / itemsBoundingRect.height();
				m_rectItem->setRect(0, 0, bgPixmapRect.width() / scaleH, bgPixmapRect.height() / scaleV);
				m_rectItem->setPos(offsetXRatio * bgPixmapRect.width() + m_bgPixmapItem->x(), offsetYRatio * bgPixmapRect.height() + m_bgPixmapItem->y());
			}

			// 显示缩放比率
			if (scaleMax != 0)
				ui.lblScale->setText(QString("%1%").arg((int)(scaleMax * 100)));
		}
	}
	else if (watched == m_mainView->viewport())
	{
		if (event->type() == QEvent::MouseMove)
		{
			QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
			if (mouseEvent->buttons() != Qt::LeftButton)
				return QWidget::eventFilter(watched, event);

			QGraphicsScene *scene = m_mainView->scene();
			QRectF itemsBoundingRect = scene->itemsBoundingRect();

			// 计算缩放后的图元大小与主视窗大小的水平/垂直比率
			QRectF bgPixmapRect = m_bgPixmapItem->boundingRect();
			QSize mainViewportSize = m_mainView->viewport()->rect().size();
			qreal scaleFactor = m_mainView->matrix().m11();
			double scaleH = itemsBoundingRect.width() * scaleFactor / mainViewportSize.width();
			double scaleV = itemsBoundingRect.height() * scaleFactor / mainViewportSize.height();
			double scaleMax = qMax(scaleH, scaleV);
			if (scaleMax > 1)
			{// 当比率>1时,矩形导航框为主视窗中图元占整个场景图元的比率所对应的鹰眼视图大小
				QPointF viewportTopLeftToScenePos = m_mainView->mapToScene(QPoint(0, 0));
				double offsetXRatio = (viewportTopLeftToScenePos.x() - itemsBoundingRect.x()) / itemsBoundingRect.width();
				double offsetYRatio = (viewportTopLeftToScenePos.y() - itemsBoundingRect.y()) / itemsBoundingRect.height();
				m_rectItem->setRect(0, 0, bgPixmapRect.width() / scaleH, bgPixmapRect.height() / scaleV);
				m_rectItem->setPos(offsetXRatio * bgPixmapRect.width() + m_bgPixmapItem->x(), offsetYRatio * bgPixmapRect.height() + m_bgPixmapItem->y());
			}
		}
	}
	else if (watched == ui.graphicsView->viewport())
	{
		if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseMove)
		{
			QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
			QRectF bgPixmapRect = m_bgPixmapItem->boundingRect();
			QGraphicsScene *scene = m_mainView->scene();
			QRectF itemsBoundingRect = scene->itemsBoundingRect();

			// 换算鼠标点击处在场景中的位置,并将该位置设置为视野中心
			double offsetX = mouseEvent->x() - m_bgPixmapItem->x();
			double offsetY = mouseEvent->y() - m_bgPixmapItem->y();
			double scale = bgPixmapRect.width() / itemsBoundingRect.width();
			double sceneOffsetX = itemsBoundingRect.x() + offsetX / scale;
			double sceneOffsetY = itemsBoundingRect.y() + offsetY / scale;
			m_mainView->centerOn(sceneOffsetX, sceneOffsetY);

			// 计算缩放后的图元大小与主视窗大小的水平/垂直比率
			QSize mainViewportSize = m_mainView->viewport()->rect().size();
			qreal scaleFactor = m_mainView->matrix().m11();
			double scaleH = itemsBoundingRect.width() * scaleFactor / mainViewportSize.width();
			double scaleV = itemsBoundingRect.height() * scaleFactor / mainViewportSize.height();
			double scaleMax = qMax(scaleH, scaleV);
			if (scaleMax > 1)
			{// 当比率>1时,设置矩形导航框位置
				QPointF scenePos = ui.graphicsView->mapToScene(mouseEvent->pos());
				m_rectItem->setPos(scenePos.x() - m_rectItem->rect().width() / 2, scenePos.y() - m_rectItem->rect().height() / 2);
			}
		}
	}

	return QWidget::eventFilter(watched, event);
}

void EagleWidget::on_btnClose_clicked()
{
	close();
}

到了这里,关于Qt实现思维导图功能6『鹰眼视图』的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • QT图形视图系统 - 使用一个项目来学习QT的图形视图框架 - 终篇

    接上一篇,我们需要继续完成以下的效果; 先上个效果图: 资源路径:https://download.csdn.net/download/turbolove/88192114?spm=1001.2014.3001.5503 上一篇我们绘制了标尺,并且我们修改了放大缩小和对应的背景,整体看来,我们的滚动条会和背景不搭配,因此我们需要修改我们的背景,这

    2024年02月13日
    浏览(10)
  • AIGC功能在线制作思维导图?

    ProcessOn思维导图软件是一款功能强大的在线制作思维导图的工具,它提供了丰富的模板和图标,可以帮助用户快速制作出高质量的思维导图。其中,AIGC(人工智能图形识别)功能是 ProcessOn软件中的一大特色,它可以帮助用户更加高效地制作思维导图。下面,我们将详细介绍如何

    2024年02月09日
    浏览(45)
  • C++ Qt开发:TabWidget实现多窗体功能

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍 TabWidget 标签组件的常用方法及灵活运用。 QTabWidget 是Qt中用于实现标签页(t

    2024年02月04日
    浏览(14)
  • Qt5开发及实例V2.0-第七章-Qt图形视图框架

    7.1.1 Graphics View的特点 Graphics View框架结构的主要特点如下。 (1)Graphics View框架结构中,系统可以利用Qt绘图系统的反锯齿、OpenGL工具来改善绘图性能。 (2)Graphics View支持事件传播体系结构,可以使图元在场景(scene)中的交互能力提高1倍,图元能够处理键盘事件和鼠标事

    2024年02月07日
    浏览(12)
  • 界面开发框架Qt新手入门教程:Dir视图使用实例

    Qt 是目前最先进、最完整的跨平台C++开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。 点击获取Qt Widget组件下载 本示例演示了树形视图的用

    2024年02月08日
    浏览(13)
  • QT 项目视图(QListView&QTreeView&QTableView)和项目部件(QListWidget&QTreeWidget&QTableWidget)详解

    目录 一、Qt 项目视图(Item Views)         1.QListView 2.QTreeView 3.QTableView 二、Qt 项目部件(Item Widgets) 1.QListWidget 2.QTreeWidget 3.QTableWidget 一、Qt 项目视图(Item Views)          控件名称依次解释如下: List View:清单视图 Tree View: 树视图 Table View:表视图 Column View: 列视图 Undo Vie

    2024年01月20日
    浏览(21)
  • vue实现思维导图

    介绍 前景: 仿幕布实现思维导图效果 技术实现: jsmind 完整代码 :vue-jsmind 参考文章: 在vue中使用jsmind组织架构或思维导图 实现效果: 功能描述: 编辑、删除、插入、拖拽、展开/收起节点 分布结构切换(向左、向右和两边分布) 节点类型筛选 导出图片 鼠标左键拖拽 缩

    2023年04月13日
    浏览(24)
  • 信息系统项目管理师教程 第四版【第8章-项目整合管理-思维导图】

    信息系统项目管理师教程 第四版【第8章-项目整合管理-思维导图】 课本里章节里所有蓝色字体的思维导图

    2024年02月07日
    浏览(18)
  • 信息系统项目管理师(第四版)教材精读思维导图-第七章项目立项管理

      请参阅我的另一篇文章,综合介绍软考高项: 信息系统项目管理师(软考高项)备考总结_计算机技术与软件专业技术_铭记北宸的博客-CSDN博客 本章思维导图PDF格式 本章思维导图XMind源文件 ​  目录 7.1 项目建议与立项申请 7.2 项目可行性研究 7.3 项目评估与决策 立项申请

    2024年02月11日
    浏览(15)
  • 信息系统项目管理师教程 第四版【第6章-项目管理概论-思维导图】

    信息系统项目管理师教程 第四版【第6章-项目管理概论-思维导图】 课本里章节里所有蓝色字体的思维导图

    2024年02月08日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包