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);
                }
            }
    
    }
    
    
    

    全部评论

    相关推荐

    1 3 评论
    分享
    牛客网
    牛客企业服务