文件对比工具实现,以二进制和明文显示比较结果

效果图:候补

具体实现(核心代码带释义)

项目配置:

QT       += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = bindiff-qt

TEMPLATE = app

*-g++*:QMAKE_CXXFLAGS += -Wall -Weffc++ -Wextra -Wconversion -Wsign-conversion -std=c++14

SOURCES += main.cpp\
    mainwindow.cpp \
    binfileview.cpp

HEADERS  += mainwindow.h \
    binfileview.h

FORMS    += mainwindow.ui

OTHER_FILES += license.txt

INSTALLS += target

unix{
    target.path = /bin
    message( The executable will be installed to $$target.path )
}

main.cpp


#include "mainwindow.h"
#include 
#include 

int main( int argc, char* argv[] )
{
    QFileInfo execFile( argv[0] );
    QCoreApplication::setApplicationName( execFile.fileName() );
    QApplication a( argc, argv );
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.h/cpp/ui


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 


namespace Ui {
class MainWindow;
}
class QFile;
class BinFileView;

struct FileModel
{
    FileModel( QFile* file, uchar* mmap ) : _file( file ), _mmap( mmap ) {}
    QFile* _file;
    uchar* _mmap;
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow( QWidget* parent = nullptr );
    ~MainWindow();

private slots:
    void open( BinFileView* );
    void open( const QString&, BinFileView* view = nullptr );
    void updateDiff( BinFileView* );
    void on_actionE_xit_triggered();

private: // No copying
    MainWindow( const MainWindow& );
    MainWindow& operator=( const MainWindow& );

private: // Data
    Ui::MainWindow* ui;
    QMap _files;
    uchar* _diffMap;
    qint64 _diffMapSize;
};

#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include 
#include 
#include 
#include 

MainWindow::MainWindow( QWidget *parent ) :
    QMainWindow( parent ),
    ui( new Ui::MainWindow ),
    _diffMap( nullptr ),
    _diffMapSize( 0 )
{
    ui->setupUi( this );

    setWindowTitle( QCoreApplication::applicationName() );

//    ui->binFileView1->setAcceptDrops( true );
//    ui->binFileView2->setAcceptDrops( true );

    ui->binFileView1->setFont( QFont( "Monospace", 10 ) );
    ui->binFileView2->setFont( QFont( "Monospace", 10 ) );

    // Cross-connect vertical & horizontal scroll bars
    connect( ui->binFileView1->verticalScrollBar(), \
             SIGNAL( valueChanged( int ) ), \
             ui->binFileView2->verticalScrollBar(), \
             SLOT( setValue( int ) ) );
    connect( ui->binFileView2->verticalScrollBar(), \
             SIGNAL( valueChanged( int ) ), \
             ui->binFileView1->verticalScrollBar(), \
             SLOT( setValue( int ) ) );

    connect( ui->binFileView1->horizontalScrollBar(), \
             SIGNAL( valueChanged( int ) ), \
             ui->binFileView2->horizontalScrollBar(), \
             SLOT( setValue( int ) ) );
    connect( ui->binFileView2->horizontalScrollBar(), \
             SIGNAL( valueChanged( int ) ), \
             ui->binFileView1->horizontalScrollBar(), \
             SLOT( setValue( int ) ) );

    // to maintain consistent width for both views
    connect( ui->binFileView1, SIGNAL( defaultVisualsChanged( BinFileView* ) ), \
             ui->binFileView2, SLOT( synchronizeVisuals( BinFileView* ) ) );
    connect( ui->binFileView2, SIGNAL( defaultVisualsChanged( BinFileView* ) ), \
             ui->binFileView1, SLOT( synchronizeVisuals( BinFileView* ) ) );

    // File drag & drop signals
    connect( ui->binFileView1, SIGNAL( fileDropped( QString, BinFileView* ) ), \
             this, SLOT( open( QString, BinFileView* ) ) );
    connect( ui->binFileView2, SIGNAL( fileDropped( QString, BinFileView* ) ), \
             this, SLOT( open( QString, BinFileView* ) ) );

    // And view's file ctx menu signals
    connect( ui->binFileView1, SIGNAL( fileOpenRequested( BinFileView* ) ), \
             this, SLOT( open( BinFileView* ) ) );
    connect( ui->binFileView2, SIGNAL( fileOpenRequested( BinFileView* ) ), \
             this, SLOT( open( BinFileView* ) ) );

    // On demand (i.e. via changed content of view's data) requested diffing
    connect( ui->binFileView1, SIGNAL( fileViewContentChanged( BinFileView* ) ), \
             this, SLOT( updateDiff( BinFileView* ) ), Qt::DirectConnection );
    connect( ui->binFileView2, SIGNAL( fileViewContentChanged( BinFileView* ) ), \
             this, SLOT( updateDiff( BinFileView* ) ), Qt::DirectConnection );

    // Get the arguments
    if( QCoreApplication::arguments().size() == 3 ) {
        open( QCoreApplication::arguments().at( 1 ), ui->binFileView1 );
        open( QCoreApplication::arguments().at( 2 ), ui->binFileView2 );
    }
}

MainWindow::~MainWindow()
{
    delete ui;

    //代码中使用了内存映射,所以需要对资源及时释放
    if( !_files.empty() ) {
        for( const auto f : _files ) {
            f._file->unmap( f._mmap );
            f._file->close();
            delete f._file;
        }
    }
    if( _d

你可能感兴趣的:(QtDemo,qt,qt5,文件比较,文件比对,二进制,bycompare)