qml实现文本二进制互转工具

  • 下载

windows环境,文本二进制互转工具下载:https://download.csdn.net/download/lewanhah01/11831813

  • 界面及功能

首先实现的界面效果如下:

二进制转文本( img.bin -> img.bin.txt)

而文本转二进制是上面的反操作。

  • 实现

首先是main入口函数(main.c)

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQuickControls2>
#include "file_convert.h"
#include <QVariant>

QObject *gObject;

void showMessage(QVariant value)
{
    gObject->setProperty("text", value);
}

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    //使用系统自带style
    QQuickStyle::setStyle("Universal");
    QQmlApplicationEngine engine;

    //创建对象并设置,之后可以在qml中以“FILECONVERT”名称使用
    FileConvert fileConvert;
    engine.rootContext()->setContextProperty("FILECONVERT",&fileConvert);
    

    engine.load(QUrl(QLatin1String("qrc:/main.qml")));

    //设置全局变量,供C++调用qml成员
    QObject *root = engine.rootObjects().first();
    gObject = root->findChild<QObject *>("tipLabelObj");
    if (!gObject) { return -1;}

    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml是界面相关的代码:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Controls 2.2

ApplicationWindow {
    visible: true
    width: 520
    height: 210
    title: qsTr("文本二进制互转工具V0.1  作者:大樹([email protected])")

    property bool isTxt2Bin: true        //定义bool类型的属性变量
                                         //true表示文本转二进制,false表示二进制转文本

    Rectangle {
        id: fileListShow
        anchors.left: parent.left
        anchors.leftMargin: 2
        anchors.top: parent.top
        anchors.topMargin: 2

        width: parent.width/3*2
        height: parent.height - 2
        border.width: 1
        border.color: "#363636"
        radius: 1

        //选中文件后,路径/文件名显示
        Text {
            width: parent.width - 5
            id: labels
            //text: "file:///C:/Users/Administrator/Desktop/kernel_data.bin.txt"
            wrapMode: Text.WrapAnywhere
            font.family: "宋体"
            font.pixelSize: 14
        }
    }

    Rectangle {
        id:controlArea
        anchors.left: fileListShow.right
        anchors.top: parent.top
        anchors.topMargin: 10
        width: parent.width/3 - 4
        height: parent.height - 2

        Button {
            id:openBtn
            height: 32
            width: parent.width - 20
            text:qsTr("选择文件")
            anchors.top: parent.top
            anchors.margins: 5
            anchors.horizontalCenter: parent.horizontalCenter

            onClicked: {
                fds.open();    //打开文件对话选择框
            }
        }

        Button {
            id:convertBtn
            height: 32
            width: parent.width - 20
            text:qsTr("开始转换")
            anchors.top: openBtn.bottom
            anchors.margins: 5
            anchors.horizontalCenter: parent.horizontalCenter

            onClicked: {
                if(FILECONVERT.fileName == "") {
                    tipLabel.text = "未选择转换文件"
                }
                else {
                    if(isTxt2Bin)
                        FILECONVERT.doConvert(1); //调用c++方法,传入参数1,表示文本转二进制
                    else
                        FILECONVERT.doConvert(2); //调用c++方法,传入参数2,表示二进制转文本
                }
            }
        }

        Button {
            id:tipBtn
            height: 32
            width: parent.width - 20
            text:qsTr("说明")
            anchors.top: convertBtn.bottom
            anchors.margins: 5
            anchors.horizontalCenter: parent.horizontalCenter

            onClicked: {
                msgDialog.open(); //弹出消息对话框
            }
        }

        MessageDialog {
            id:msgDialog
            width: 520
            height: 180
            //buttons: MessageDialog.Ok
            text: "文本二进制互转工具使用说明"
            informativeText: "\n二进制转文本,会在每个字节前面加\"0x\"头部,并使用空格分隔;\n文本转二进制,自动过滤\"0x\"、空格、换行符;"
        }

        FileDialog {
            id:fds
            title: "选择文件"
            folder: shortcuts.desktop
            selectExisting: true
            selectFolder: false
            selectMultiple: false
            nameFilters: ["txt文件 (*.txt)","bin文件 (*.bin)"]
            onAccepted: {
                labels.text = fds.fileUrl;                
                FILECONVERT.fileName = fds.fileUrl
                tipLabel.text = ""
                //根据文件名后缀,自动选择转换类型
                var suffix = FILECONVERT.fileName.substring(FILECONVERT.fileName.length - 4);
                if(suffix == ".txt")
                    isTxt2Bin = true;
                else
                    isTxt2Bin = false;
            }

            onRejected: {
                //if (labels.text == "")
                    //tipLabel.text = "未选中文件"
            }
        }

        //下面是转换类型,由两个勾选框实现
        //isTxt2Bin记录转换类型,CheckBox的操作会修改isTxt2Bin,触发IsTxt2BinChanged信号
        //从而onIsTxt2BinChanged槽函数被执行,文本转二进制/二进制转文本为非此即彼的关系
        Column {
            anchors.top: tipBtn.bottom
            anchors.topMargin: 2
            anchors.left: parent.left
            anchors.leftMargin: 10

            CheckBox {
                id: txt2binCB
                text: qsTr("文本转二进制")
                checked: true

                onClicked: {
                    isTxt2Bin = !isTxt2Bin
                }
            }
            CheckBox {
                id: bin2txtCB
                text: qsTr("二进制转文本")
                checked: false

                onClicked: {
                    isTxt2Bin = !isTxt2Bin
                }
            }
        }
    }

    onIsTxt2BinChanged: {
        txt2binCB.checked = isTxt2Bin
        bin2txtCB.checked = !isTxt2Bin
    }

    //底部的显示栏,用于显示执行状态信息
    footer: Item {
        height: 20
        width: parent.width

        Rectangle {
            anchors.fill: parent
            anchors.topMargin: 2
            color: "#EEEEEE"
            Label {
                id: tipLabel
                objectName: "tipLabelObj"
                anchors.left: parent.left
                anchors.leftMargin: 5
                font.family: "宋体"
                font.pixelSize: 14
                //anchors.horizontalCenter: parent.horizontalCenter
            }
        }
    }
}

上面qml调用了C++对象FileConvert的fileName属性和doConvert方法,FileConvert对象定义如下:

#ifndef FILE_CONVERT_H
#define FILE_CONVERT_H

#include <QObject>

class FileConvert : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString fileName READ getFileName WRITE setFileName NOTIFY fileNameChanged)
    Q_PROPERTY(int process READ getProcess WRITE setProcess NOTIFY processChanged)
public:
    explicit FileConvert(QObject *parent = nullptr);

    QString getFileName() const{return fileName;}
    void setFileName(QString s){fileName = s; emit fileNameChanged();}

    int getProcess() const{return process;}
    void setProcess(int v){process = v; emit processChanged();}

signals:
    void fileNameChanged();
    void processChanged();

public slots:
public:
    Q_INVOKABLE void doConvert(int type);
private:
    QString fileName;
    int process;
    int txt2bin(FILE* fpin,FILE* fpout, long size);
    int bin2txt(FILE* fpin,FILE* fpout, long size);
};

#endif // FILE_CONVERT_H

上面包含了qml调用C++需要的定义,可参考qml与C++交互的相关内容,下面看下doConvert的实现(qml调用C++的方法,定义时必须加上Q_INVOKABLE关键字)

void FileConvert::doConvert(int type)
{
    char input[4096];
    char output[4096];
    char tmp[4096];
    std::string str;
    FILE* fp;
    FILE* outfp;
    //struct stat statbuf;
    long size;
    int ret;

    memset(input, 0, sizeof(input));
    memset(output, 0, sizeof(output));
    memset(tmp, 0, sizeof(tmp));

    str = fileName.toStdString();
    strcpy(tmp, str.c_str());
    if(strlen(tmp) == 0) {
        qDebug()<<"fileName is Empty";
        return;
    }
    //使用fopen打开文件,需要去掉"file:///"前缀
    memmove(input, tmp + strlen("file:///"), strlen(tmp) - strlen("file:///"));
    qDebug()<<"fileName:"<<fileName<<", input:"<<input;

    //以读、二进制方式打开文件
    fp = fopen(input,"rb+");
    if(fp == NULL)
    {
        qDebug()<<"open failed "<<input;
        return;
    }

    //stat(input, &statbuf);
    //size = statbuf.st_size;
    //读取文件大小
    fseek(fp,0L,SEEK_END);
    size=ftell(fp);
    fseek(fp,0L,SEEK_SET);

    qDebug()<<"file size "<<size;

    //根据转换类型,增加目标文件的后缀
    sprintf(output, "%s%s", input, (type == CONVERT_TXT2BIN) ? ".bin" : ".txt");
    outfp = fopen(output,"wb+");
    if(outfp == NULL)
    {
        qDebug()<<"open failed "<<output;
        fclose(fp);
        return;
    }

    //表示转换进度
    process = 0;

    //根据转换类型,调用不同的方法进行转换
    if(type == CONVERT_TXT2BIN) {
        ret = txt2bin(fp, outfp, size);
    }
    else {//if(type == CONVERT_BIN2TXT) {
        ret = bin2txt(fp, outfp, size);
    }

    //根据执行转换函数的返回值,设置qml底部显示栏显示(c++调用qml成员)
    if(ret == -FILE_FD_ERR) {
        QVariant msg = "文件读写失败";
        showMessage(msg);
    }
    else if(ret == -FILE_FMT_ERR) {
        QVariant msg = "文件格式错误";
        showMessage(msg);
    }
    else {
        QVariant msg = "完成";
        showMessage(msg);
    }

    fclose(fp);
    fclose(outfp);
    return;
}
  • 工程源码

项目代码已上传github托管,下载https://github.com/baiyou123/TxtBinConverter

发布了18 篇原创文章 · 获赞 6 · 访问量 6361

猜你喜欢

转载自blog.csdn.net/lewanhah01/article/details/101980890