我们知道,在QML应用中,有时我们需要来读写一些文件,但是在我们的QML语言中并没有相应的API接口来供我们做(虽然有API接口来存储设置文件等)。那么我们怎么来做这个事情呢?我们可以通过Qt C++的方法来实现这个功能。
1)创建一个简单的模版应用
我们使用Ubuntu SDK的模版来创建一个最简单的应用:
我们选择“
QML App with C++ plugin”模版来做我们的应用。
2)添加文件读写的文件到项目中
我们添加如下的C++ "FileIO类到我们的backend plugin中:
#ifndef FILEIO_H
#define FILEIO_H
#include <QObject>
#include <QTextCodec>
#include <QDebug>
class FileIO : public QObject
{
Q_OBJECT
public:
Q_PROPERTY(QString source
READ source
WRITE setSource
NOTIFY sourceChanged)
explicit FileIO(QObject *parent = 0);
Q_INVOKABLE QString read();
Q_INVOKABLE bool write(const QString& data);
QString source() { return mSource; };
public slots:
void setSource(const QString& source) { mSource = source; };
signals:
void sourceChanged(const QString& source);
void error(const QString& msg);
private:
QString getenv(const QString envVarName) const;
private:
QString mSource;
QString datapath;
};
inline QString GBK2UTF8(const QString &inStr)
{
QList<QByteArray> codecs = QTextCodec::availableCodecs();
for ( int i = 0; i < codecs.length(); i ++ ) {
// qDebug() << "codec: " + QTextCodec::codecForMib(1015)->toUnicode(codecs.at(i));
qDebug() << "codec: " << QString::fromLocal8Bit(codecs.at(i));
}
QTextCodec *gbk = QTextCodec::codecForName("GBK");
QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());
// QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
QString g2u = gbk->toUnicode(gbk->fromUnicode(inStr)); // gbk convert utf8
return g2u;
}
#endif // FILEIO_H
#include "fileio.h"
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QFileInfo>
#include <QTextCodec>
FileIO::FileIO(QObject *parent) : QObject(parent)
{
datapath = getenv("TMPDIR") + "/";
qDebug() << "datapath: " + datapath;
}
QString FileIO::read()
{
qDebug() << "reading ....!";
if (mSource.isEmpty()){
emit error("source is empty");
return QString();
}
QFile file(datapath + mSource);
QFileInfo fileInfo(file.fileName());
qDebug() << "file path: " << fileInfo.absoluteFilePath();
QString fileContent;
if ( file.open(QIODevice::ReadOnly) ) {
QString line;
QTextCodec *gbk = QTextCodec::codecForName("GBK");
QTextStream t( &file );
t.setCodec(gbk);
do {
line = t.readLine();
fileContent += line;
} while (!line.isNull());
file.close();
return fileContent;
} else {
emit error("Unable to open the file");
return QString();
}
}
bool FileIO::write(const QString& data)
{
qDebug() << "writing.....";
if (mSource.isEmpty())
return false;
QFile file(datapath + mSource);
QFileInfo fileInfo(file.fileName());
qDebug() << "file path: " << fileInfo.absoluteFilePath();
if (!file.open(QFile::WriteOnly | QFile::Truncate))
return false;
QTextStream out(&file);
out << data;
file.close();
return true;
}
QString FileIO::getenv(const QString envVarName) const
{
QByteArray result = qgetenv(envVarName.toStdString().c_str());
QString output = QString::fromLocal8Bit(result);
qDebug() << envVarName << " value is: " << output;
return output;
}
这个类是可以向我们指定的文件地址读写文件。注意,我们使用了getenv来获取可以读写的文件目录。Ubuntu应用不是可以打开任何一个文件目录进行读写的。具体可以参考文章“ Ubuntu OS应用Runtime Enviroment”来得到更多的了解。在这个例程中,我们指定了文件的编码方式为GBK。你们可以不指定或指定为你所需要的编码方式。
在backend的CMakeLists.txt中加入:
modules/ReadFileQML/fileio.cpp
同时在backend.cpp中加入:
void BackendPlugin::registerTypes(const char *uri)
{
Q_ASSERT(uri == QLatin1String("ReadFileQML"));
qmlRegisterType<MyType>(uri, 1, 0, "MyType");
qmlRegisterType<FileIO>(uri, 1, 0, "FileIO"); // added line
}
这样就完成了我们的plugin的设计。
3)在应用中调用
为了测试我们的plugin,我们修改我们的readfileqml.qml文件如下:
import QtQuick 2.0
import Ubuntu.Components 1.1
import ReadFileQML 1.0
/*!
\brief MainView with Tabs element.
First Tab has a single Label and
second Tab has a single ToolbarAction.
*/
MainView {
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView"
// Note! applicationName needs to match the "name" field of the click manifest
applicationName: "readfileqml.liu-xiao-guo"
/*
This property enables the application to change orientation
when the device is rotated. The default is false.
*/
//automaticOrientation: true
// Removes the old toolbar and enables new features of the new header.
useDeprecatedToolbar: false
width: units.gu(60)
height: units.gu(76)
Page {
title: i18n.tr("Read File QML")
Text {
id: myText
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: button.top
wrapMode: Text.Wrap
}
Button {
id: button
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom:parent.bottom
height: units.gu(5)
text: "Reload file"
onClicked: {
console.log("button is clicked!");
//reload the file
myText.text = myFile.read();
}
}
FileIO {
id: myFile
source: "good.txt"
onError: console.log(msg)
}
Component.onCompleted: {
console.log( "WRITE: "+ myFile.write("this is really cool!"));
console.log("source: " + myFile.source );
myText.text = myFile.read();
}
}
}
这里,我们定义了:
FileIO {
id: myFile
source: "good.txt"
onError: console.log(msg)
}
我们可以通过它向我们的文件“good.txt”来读写文件了。注意good.txt文件的地址。