前文链接:Qt实现思维导图功能(二)
思维导图文件导入与导出
本文主要涉及文件拖拽窗口的实现和CRC32校验码的生成方法
百度网盘体验地址: 链接:https://pan.baidu.com/s/1T9Zhe18BHFLmIsRPcyTk7Q 提取码:6a8k
效果图
1、动态演示效果:
2、静态展示图片
新增文件导出功能如下
| 序号 | 简述 | 具体功能 |
|---|---|---|
| 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 #includeclass 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) : 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
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);
}



