Qt中实现文件(文本文件)内容对比

发布于:2025-07-17 ⋅ 阅读:(14) ⋅ 点赞:(0)

假如想实现类似VSCode的文件对比功能的话
在这里插入图片描述

有个库【diff-match-patch】,可以实现类似的功能。
将库下载下来后,我们只要将其源码cpp文件夹下的diff_match_patch.h, diff_match_patch.cpp这两个文件加到我们工程中
在这里插入图片描述

在这里插入图片描述
然后自己利用其提供的功能实现一下即可(使用QTextEdit来显示):

#include "diff_match_patch.h"

// 读取文件内容
QString readFile(const QString& filePath) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return QString();
    }
    return QString::fromUtf8(file.readAll());
}

// 在QTextEdit中显示带颜色标记的差异
void showColoredDiff(QTextEdit* textEdit, const QString& text1, const QString& text2) {
    diff_match_patch dmp;

    // 计算差异
    auto diffs = dmp.diff_main(text1, text2);
    dmp.diff_cleanupSemantic(diffs);  // 优化差异结果

    // 准备文本格式
    QTextCharFormat normalFormat;
    QTextCharFormat addedFormat;
    QTextCharFormat removedFormat;

    addedFormat.setBackground(Qt::green);      // 新增内容绿色背景
    removedFormat.setBackground(Qt::red);       // 删除内容红色背景
    removedFormat.setFontStrikeOut(true);       // 删除线

    // 清空并重置文本编辑器
    textEdit->clear();
    QTextCursor cursor(textEdit->document());
    // 应用差异格式
    for (const auto& diff : diffs) {
        qDebug() << diff.toString() << diff.text;
        switch (diff.operation) {
        case INSERT:
            cursor.setCharFormat(addedFormat);
            cursor.insertText(diff.text);
            break;
        case DELETE:{
            cursor.setCharFormat(removedFormat);
            QString tmpStr = diff.text;
            qDebug() << diff.text.endsWith("\n");
            if(diff.text.endsWith("\n"))
            {
                tmpStr.replace("\n", "\n ");
            }
            cursor.insertText(tmpStr);
        }break;
        case EQUAL:
            cursor.setCharFormat(normalFormat);
            cursor.insertText(diff.text);
            break;
        }
    }

    // textEdit->setHtml(dmp.diff_prettyHtml(diffs));
}

// 使用示例
void compareFiles(const QString& filePath1, const QString& filePath2, QTextEdit* output) {
    QString content1 = readFile(filePath1);
    QString content2 = readFile(filePath2);

    if (content1.isEmpty() || content2.isEmpty()) {
        output->setPlainText("Error reading files");
        return;
    }

    showColoredDiff(output, content1, content2);
}

// 调用
{
    QTextEdit edit;
    compareFiles("main.txt", "main_.txt", &edit);
    edit.resize(640, 480);
    edit.show();
}

在这里插入图片描述

这样子就可以体现从a.txt–>b.txt需要发生哪些变化,图上的红色背景表示删除、绿色背景表示增加、白色背景表示不改变。
从他的源码看看
在这里插入图片描述
可以看到,两个文件的内容(字符串),从其中的一个变成另外一个,无非是这三种操作(DELETE, INSERT, EQUAL)的排列组合,
而使用了diff_main之后,便可以得到这些操作的组合:
在这里插入图片描述
然后将这些组合依次组合起来便得到了差异。


参考
【diff-match-patch】


网站公告

今日签到

点亮在社区的每一天
去签到