- 下载
windows环境,文本二进制互转工具下载:
- 界面及功能
首先实现的界面效果如下:
二进制转文本( 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 作者:大樹(842577951@qq.com)")
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;
}