Qt实现GUI的二进制文件读写操作(源码分析+工程打包+测试例子)

本人小菜一枚,上周老大要写一个Qt软件
需求:实现二进制文件读写,写入Version(如intx型 104)、累加校验和(int型sum)、字符串(“deadbeaf”)

其实在二进制的read上,是不做要求的,我目前用的是QTextStream读取的文本文件,并非QDataStream读取的二进制文件,所以这点说明下。

源码+可执行文件+测试.bin文件 一并打包上传 资源

实现的环境是 Ubuntu 14.04 32位,64可能直接运行可执行文件出错,需要你重新编译后执行

学习是和一个豆子的大神学习Qt的,目前才看了20个不到,一起加油!豆哥博客

mainwindow.h头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 

class QTextEdit;
class QLineEdit;
class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();


private: //Action
    QAction   *openAction;
    QAction   *saveAction;
    QTextEdit *textEdit;

private:  //变量
    QLineEdit *Version;

private slots: //槽
    void openFile();
    void saveFile();
    int CKS();

};

#endif // MAINWINDOW_H

main.cpp

#include 
#include "mainwindow.h"
#include "QIODevice"
#include "QFile"
#include "QFileInfo"
#include "QDebug"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.cpp

#include 
#include 
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    QWidget *w = new QWidget(this); //控件对象
    this->setCentralWidget(w);

    Version = new QLineEdit(w); //单行文本输入域 version对象
    Version->setPlaceholderText("Version");

    textEdit = new QTextEdit(this);   //创建文本窗口域


    QGridLayout *grid = new QGridLayout(w);//网格布局对象
    grid->addWidget(Version, 0, 0, 0);
    grid->addWidget(textEdit,1, 0, 0);

    openAction = new QAction(QIcon(":/images/file-open"), tr("&Open..."), this);
    openAction->setShortcuts(QKeySequence::Open);
    openAction->setStatusTip(tr("Open an existing file"));
    connect(openAction, &QAction::triggered, this, &MainWindow::openFile);
    //将openAction这个Action与MainWindow下的openFile()连在一起,只要触发了openAction控件,就openFile一下

    saveAction = new QAction(QIcon(":/images/file-save"), tr("&Save..."), this);
    saveAction->setShortcuts(QKeySequence::Save);
    saveAction->setStatusTip(tr("Save a new file"));
    connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);


    QMenu *file = menuBar()->addMenu(tr("&File"));
    file->addAction(openAction);//增加菜单栏控件
    file->addAction(saveAction);


    QToolBar *toolBar = addToolBar(tr("&File"));
    toolBar->addAction(openAction);//增加工具栏控件
    toolBar->addAction(saveAction);

    //布局
    QHBoxLayout* passwordEditLayout = new QHBoxLayout();//左右排列对象
    passwordEditLayout->addStretch();  //Username Password 平均分配布局
    passwordEditLayout->setSpacing(0);            //设置空间之间的距离
    passwordEditLayout->setContentsMargins(0, 0, 8, 0);//设置左侧、顶部、右侧和底部边距,以便在布局周围使用。
    Version->setLayout(passwordEditLayout);  //对左右排列对象  进行布局

    //setCentralWidget(textEdit);

}

MainWindow::~MainWindow()
{
}
//--------------------采用Ascii码 计算textEdit文本框内的 Ascii编码累加和----------------------------//
int MainWindow::CKS()
{
    int len;
    QString str;
    int sum = 0;
    str = textEdit->toPlainText();   //QLineEdit的QTextEdit 用toPlainText()获取文本框内的字符串 赋给 QString的str
    len = str.length()-1;
    for(int i=0; isetText(buf);
        QTextStream in(&file);  //这里使用的QTextStream流读取的,其实并不是二进制的读取
        textEdit->setText(in.readAll());
        file.close();
    }
    else
    {
        QMessageBox::warning(this, tr("Path"), tr("You did not select any file."));
    }
}

void MainWindow::saveFile()
{
    int sum = 0;
    bool ok;
    int dec_version = 0;
    QString path = QFileDialog::getSaveFileName(this, tr("Save File"), ".", tr("Text Files(*.txt *.bin)"));
    if(!path.isEmpty())
    {
        QFile file(path);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        {
            QMessageBox::warning(this, tr("Write File"), tr("Cannot open file:\n%1").arg(path));
            return;
        }

        QDataStream out(&file);
        dec_version = Version->text().toInt(0,10);
        out.writeRawData((char*)&dec_version, 4);//writeRawData 将原始内存写入file中,可避免QDataSream默认写入时增加的len(字节长度)

        sum = CKS(); //写入版本号之后,再利用Ascii码计算累加校验和
        out.writeRawData((char*)&sum,4);
        qDebug() << "sum:" << sum;  //打印int型的sum值

        char data[8];
        memset(data,0,8*sizeof(char));
        char* p = "deadbeaf";
        strcpy(data,p);
        out.writeRawData(data,8);

//知识点1
//        QDataStream out_1(&file,QIODevice::ReadWrite); //我这里的QDataStream默认是小端,如果要想写入大端,用这里的API
//        out_1.setByteOrder(QDataStream::LittleEndian);
//知识点2
//        out << textEdit->toPlainText();                                      //单行文本输入域 version内容
//        dec_version = Version->text().toInt(0,10);                           //再转换成10进制的int型
//        QString str=QString("%1").arg(dec_version,8,16,QLatin1Char('0'));    //这里是多此一举了,将int型转为字符串,再转为int型
//        hex_version=str.toInt(&ok,16);                                       //和直接输出 hex >> dec_version一个效果
//        out << hex << dec_version;
//        out << hex << sum;                                                   //一直都在.bin文件中写入5个字节,总有个01在4字节的sum前面
//知识点2
        QString str=QString("%1").arg(sum,8,16,QLatin1Char('0'));
        //QString::arg ( int a, int fieldWidth = 0, int base = 10, const QChar & fillChar = QLatin1Char( ' ' ) )
        //a:输入的值,fieldWidth:字符宽度,base:进制,fillChar:填充字符
        sum=str.toInt(&ok,16);  //将str转成16进制的数sum,但是这里16进制的sum还是以文本写入的file,并非二进制写入file
        qDebug() << str;     //打印str的内容
        qDebug() <<"sum(int): "<

红色:Version 104
绿色:Sum 6401707   0061AEA5
灰色:deadbeaf

Qt实现GUI的二进制文件读写操作(源码分析+工程打包+测试例子)_第1张图片

你可能感兴趣的:(Qt)