qt实现文件比较
功能点
1.鼠标拖动到文本区进行读取显示
2.高亮第二个文本区的文本
核心逻辑:
每次读取文件后将文本内容存到一个QStringList中 按换行分割。
确定两个列表中较长的那个的长度。这确保在比较两个文件时,即使一个文件比另一个长,也能进行完整的行比较。
检查三种情况来判定两个文件在某行是否不同:i < lines1.size() && i >= lines2.size()如果 lines1 有这一行,但 lines2 已经没有更多行了。
i >= lines1.size() && i < lines2.size()如果 lines2 有这一行,但 lines1 已经没有更多行了。i < lines1.size() && i < lines2.size() && lines1[i].trimmed() != lines2[i].trimmed()如果两个列表都有这一行,但内容(去除前后空白后)不同。结果展示:
#ifndef MYEDIT_H
#define MYEDIT_H
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QPlainTextEdit>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include<QPainter>
class MyEdit : public QPlainTextEdit
{
Q_OBJECT
public:
MyEdit(QWidget *parent = nullptr);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dropEvent(QDropEvent *event) override;
private:
int lineNumberAreaWidth();
public:
QStringList fileLines;
private:
void loadFile(const QString &fileName);
};
#endif // MYEDIT_H
#include "MyEdit.h"
MyEdit::MyEdit(QWidget *parent): QPlainTextEdit(parent)
{
setAcceptDrops(true);
}
void MyEdit::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasUrls()) {
event->acceptProposedAction();
}
}
void MyEdit::dropEvent(QDropEvent *event)
{
const QMimeData *mimeData = event->mimeData();
if (mimeData->hasUrls()) {
QList<QUrl> urlList = mimeData->urls();
if (urlList.size() == 1) { // 只处理单个文件
QString fileName = urlList.at(0).toLocalFile();
if (!fileName.isEmpty()) {
loadFile(fileName);
event->acceptProposedAction();
}
}
}
}
void MyEdit::loadFile(const QString &fileName)
{
QFile file(fileName);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
in.setCodec("UTF-8");
QString content = in.readAll();
setPlainText(content);
file.close();
// 清空旧的内容,并存储新的每一行
fileLines.clear();
fileLines = content.split('\n', QString::KeepEmptyParts);
} else {
qDebug() << "Failed to open file:" << fileName;
}
}
#ifndef FILECOMPARER_H
#define FILECOMPARER_H
#include <QPushButton>
#include <QWidget>
#include <QTextCursor>
#include <QTextDocument>
#include <QTextBlock>
#include<QHBoxLayout>
#include<QSpacerItem>
#include"MyEdit.h"
class FileComparer : public QWidget
{
Q_OBJECT
public:
FileComparer(QWidget *parent = nullptr);
~FileComparer();
private:
void initUI();
void compareAndHighlight();
void highlightLine(const QStringList &lines1, const QStringList &lines2);
private:
MyEdit *m_beforeFile;
MyEdit *m_afterFile;
QPushButton *compareButton;
};
#endif // FILECOMPARER_H
#include "filecomparer.h"
FileComparer::FileComparer(QWidget *parent)
: QWidget(parent)
{
initUI();
}
FileComparer::~FileComparer()
{
}
void FileComparer::initUI()
{
this->resize(800,650);
QVBoxLayout *layout = new QVBoxLayout(this);
m_beforeFile = new MyEdit(this);
m_afterFile = new MyEdit(this);
compareButton = new QPushButton("比较文件", this);
QHBoxLayout *hb1=new QHBoxLayout;
hb1->addWidget(m_beforeFile);
hb1->addWidget(m_afterFile);
QHBoxLayout *hb2=new QHBoxLayout;
hb2->addWidget(compareButton);
hb2->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding));
layout->addLayout(hb1);
layout->addLayout(hb2);
setLayout(layout);
this->m_afterFile->setStyleSheet("border:2px solid red");
this->m_beforeFile->setStyleSheet("border:2px solid blue");
connect(compareButton, &QPushButton::clicked, this, &FileComparer::compareAndHighlight);
}
void FileComparer::compareAndHighlight()
{
highlightLine(m_beforeFile->fileLines,m_afterFile->fileLines);
}
void FileComparer::highlightLine(const QStringList &lines1, const QStringList &lines2)
{
int maxLines = qMax(lines1.size(), lines2.size());
QTextCharFormat format;
format.setBackground(Qt::yellow);
for (int i = 0; i < maxLines; ++i) {
if ((i < lines1.size() && i >= lines2.size()) || (i >= lines1.size() && i < lines2.size()) ||
(i < lines1.size() && i < lines2.size() && lines1[i].trimmed() != lines2[i].trimmed())) {
QTextCursor cursor(m_afterFile->document()->findBlockByLineNumber(i));
cursor.select(QTextCursor::LineUnderCursor);
cursor.mergeCharFormat(format);
}
}
}
联想公司福利 1528人发布
