Qt实现思维导图功能3『数据导入导出』

前文链接:Qt实现思维导图功能2『UI设计』
思维导图文件导入与导出
本文主要涉及文件拖拽窗口的实现和CRC32校验码的生成方法

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

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


2、静态展示图片
Qt实现思维导图功能3『数据导入导出』_第1张图片
Qt实现思维导图功能3『数据导入导出』_第2张图片
Qt实现思维导图功能3『数据导入导出』_第3张图片
Qt实现思维导图功能3『数据导入导出』_第4张图片
Qt实现思维导图功能3『数据导入导出』_第5张图片
新增文件导出功能如下

序号 简述 具体功能
1 导出JPEG图片 脑图数据插入JPEG图片中,可导入
2 导出PNG图片 脑图数据插入PNG图片中(支持CRC32数据校验 ),可导入
3 导出PDF文件 无脑图数据,不可导入
4 导出SVG文件 无脑图数据,不可导入
5 导出WORD文件 待做
6 导出TXT文件 待做
7 导出XML文件 脑图数据以Xml格式导出,可导入
8 导出JSON文件 脑图数据以Json格式导出(采用jsoncpp解析,避免QJsonDocument导致数据自动排序),可导入
9 导出脑图文件 待做

新增文件导入功能如下

序号 简述 具体功能
1 支持JPEG格式图片 根据JPEG文件格式,解析JPEG文件/JPG后缀的JPEG格式文件 ,提取脑图数据,展示脑图
2 支持PNG格式图片 根据PNG文件格式(支持CRC32数据校验 ),解析PNG文件 ,提取脑图数据,展示脑图
3 支持XML文件 解析XML文件 ,提取脑图数据,展示脑图
4 支持JSON文件 解析JSON文件(采用jsoncpp解析,避免QJsonDocument导致数据自动排序) ,提取脑图数据,展示脑图

核心代码
1、文件拖拽窗口(作为文件导入窗口的中心窗口)

#pragma once

/*
 * 思维导图-文件拖放窗口
 */

#include 

class DropFileWidget : public QWidget
{
	Q_OBJECT

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

	// 清空数据
	void clear();
	// 获取文件名
	QString getFileName();

protected:
	void paintEvent(QPaintEvent *event);
	void dragEnterEvent(QDragEnterEvent *event);
	void dragLeaveEvent(QDragLeaveEvent *event);
	void dropEvent(QDropEvent *event);

private:
	bool m_drag;				// 是否拖拽
	bool m_isMindFile;			// 是否是导图文件(是否包含导图信息)
	bool m_existMindFile;		// 是否已拖入过导图文件
	QString m_mindFileName;		// 导图文件名
	QColor m_bgColor;			// 背景色
	QColor m_mindFileColor;		// 导图文件颜色
	QColor m_otherFileColor;	// 其他文件颜色
};
#include "DropFileWidget.h"
#include 
#include 
#include 
#include 
#include "Tool/MindFileUtility.h"

#pragma execution_character_set("UTF-8")

DropFileWidget::DropFileWidget(QWidget *parent/* = nullptr*/)
	: QWidget(parent)
{
	m_drag = false;								// 是否拖拽
	m_isMindFile = false;						// 是否是导图文件(是否包含导图信息)
	m_existMindFile = false;					// 是否已拖入过导图文件
	m_bgColor = QColor(243, 243, 243);			// 背景色
	m_mindFileColor = QColor(238, 244, 255);	// 导图文件颜色
	m_otherFileColor = QColor(255, 0, 0, 58);	// 其他文件颜色

	setAcceptDrops(true);
}

DropFileWidget::~DropFileWidget()
{
}

void DropFileWidget::clear()
{
	m_drag = false;				// 是否拖拽
	m_isMindFile = false;		// 是否是导图文件(是否包含导图信息)
	m_existMindFile = false;	// 是否已拖入过导图文件
	m_mindFileName = "";
}

QString DropFileWidget::getFileName()
{
	return m_mindFileName;
}

void DropFileWidget::paintEvent(QPaintEvent *event)
{
	Q_UNUSED(event)

	int width = this->width();
	int height = this->height();
	int size = qMin(width, height);

	QPainter painter(this);
	painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
	
	// 绘制背景
	painter.setPen(Qt::NoPen);
	painter.setBrush(QBrush(m_isMindFile ? m_mindFileColor : (m_drag ? m_otherFileColor : m_bgColor)));
	painter.drawRect(rect());

	if (!m_existMindFile)
	{
		// 绘制文本
		QFont font = painter.font();
		font.setPixelSize(24);
		painter.setFont(font);
		painter.setPen(m_isMindFile ? Qt::green : (m_drag ? Qt::red : Qt::gray));
		QString text = m_isMindFile ? "文件格式正确" : (m_drag ? "文件格式错误" : "拖放文件至此");
		painter.drawText(rect(), Qt::AlignCenter, text);
	}
	else
	{
		QFileInfo fileInfo(m_mindFileName);
		QString suffix = fileInfo.suffix().toUpper();
		// 绘制图片
		QRect pixmapRect(width / 2 - size * 0.3, size * 0.1, size * 0.6, size * 0.6);
		painter.drawPixmap(pixmapRect, QPixmap(QString(":/QWHMindMap/Res/img/ExportMind/%1.png").arg(suffix)));
		// 绘制文本
		QRect textRect(0, size * 0.7, width, size * 0.2);
		painter.setPen(Qt::black);
		painter.drawText(textRect, Qt::AlignCenter, fileInfo.fileName());
	}
}

void DropFileWidget::dragEnterEvent(QDragEnterEvent *event)
{
	clear();

	// 获取文件名,解析是否是导图文件
	m_mindFileName = event->mimeData()->urls().first().toLocalFile();
	m_isMindFile = MindFileUtility::isMindFile(m_mindFileName);
	event->acceptProposedAction();

	update();
}

void DropFileWidget::dragLeaveEvent(QDragLeaveEvent *event)
{
	clear();
	update();
}

void DropFileWidget::dropEvent(QDropEvent *event)
{
	m_drag = false;

	if (m_isMindFile)
		m_existMindFile = true;

	update();
}

2、生成CRC32校验码

#pragma once

/*
 * 思维导图-CRC32工具类
 * 对于data_len + data_type + data_content + data_crc结构的PNG数据
 * CRC解析的是data_type + data_content部分,不需要data_len部分,当然更不会需要data_crc部分
 */

class CRC32
{
public:
	// 码表生成,如:X32+X26+...X1+1, poly=(1<<26)|...|(1<<1)|(1<<0)
	static void initCrc32Table(unsigned long poly);
	// 获取CRC32校验码,crc默认初始值0xFFFFFFFF
	static unsigned long crc32(unsigned char *input, int len);
	// 生成多项式G(x) = x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
	static unsigned long CRC32::poly;	// 生成多项式代码
	
private:
	// 位逆转
	static unsigned long bitReverse(unsigned long input, int bw);
	// 获取CRC32校验码
	static unsigned long crc32(unsigned long crc, unsigned char *, int len);

private:
	static unsigned long table[256];	// 校验码表
	static unsigned long crc;			// 初始值
};
#include "CRC32.h"

unsigned long CRC32::table[256] = {0};	// 校验码表
unsigned long CRC32::crc = 0xFFFFFFFF;	// 初始值
unsigned long CRC32::poly = 0x4C11DB7;	// 生成多项式代码,由G(x)演化而来

void CRC32::initCrc32Table(unsigned long poly)
{
	unsigned long c;
	poly = bitReverse(poly, 32);
	
	for (int i = 0; i < 256; i++)
	{
		c = i;
		for (int j = 0; j < 8; j++)
		{
			if (c & 1)
				c = poly ^ (c >> 1);
			else
				c = c >> 1;
		}
		table[i] = c;
	}
}

unsigned long CRC32::bitReverse(unsigned long input, int bw)
{
	unsigned long var = 0;
	
	for (int i = 0; i < bw; i++)
	{
		if (input & 0x01)
		{
			var |= 1 << (bw - 1 - i);
		}
		input >>= 1;
	}

	return var;
}

unsigned long CRC32::crc32(unsigned long crc, unsigned char *input, int len)
{
	unsigned char index;
	unsigned char *pch = input;
	for (int i = 0; i < len; i++)
	{
		index = (unsigned char)(crc ^ *pch);
		crc = (crc >> 8) ^ table[index];
		pch++;
	}
	return crc;
}

unsigned long CRC32::crc32(unsigned char *input, int len)
{
	return crc32(crc, input, len);
}

你可能感兴趣的:(Qt探索之旅,项目,qt,java,开发语言)