- 下載
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