Чтение и запись файлов в QML (Qt)

Я пытаюсь реализовать чтение и запись файлов в QML и наткнулся на связанную статью от Nokia, но не смог успешно использовать, казалось бы, очевидный пример кода. Думаю, мне не нужно говорить, что я новичок в этой области.

где разместить этот фрагмент кода (который является вторым фрагментом кода на странице. ):

#include "fileio.h"
Q_DECL_EXPORT int main(int argc, char *argv[])
{
    qmlRegisterType<FileIO, 1>("FileIO", 1, 0, "FileIO");
}

Я также продолжаю получать ошибку в отношении qmlRegisterType, не зарегистрированного в контексте, когда Я помещаю приведенный выше фрагмент кода в свою основную форму. Может кто-нибудь посоветовать, как это реализовать (или любой метод чтения и записи файлов в QML / Qt)?

4 ответов


пример, написанный Nokia в учебнике, не является чистой программой QML. Он содержит как C++, так и QML. Такая программа обычно является программой на C++, которая загружает файл QML и отображает его. Программы на C++ обычно начинаются с функции int main(int argc, char *argv[]);. В вашем случае это функция "main ()", которая загружает ваш основной файл QML (main.qml) файл и отображает его.

но перед загрузкой основного файла QML вы должны сообщить системе QML, что вы будете использовать пользовательский класс QML под названием FileIO. Для этого вам придется использовать int qmlRegisterType<T>(const char * package, int majorVersion, int minorVersion, char * classNameInQML); функции C++. Она занимает около 5 параметров :

  • T: параметр шаблона C++. Это ваш класс C++ (FileIO).
  • пакета: все классы QML находятся в пакете, который versionned. Это название пакета.
  • majorVersion: все классы QML находятся в пакете, который versionned. Это основной номер версии пакет.
  • minorVersion: все классы QML находятся в пакете, который versionned. Это номер младшей версии пакета.
  • classNameInQML: все классы QML находятся в пакете, который versionned. Это имя вашего класса, которое вы будете использовать в файлах QML большую часть времени имя совпадает с именем класса C++.

для использования этой функции необходимо включить заголовок C++ в файл c++ где вы это пишете:

  • если вы используете Qt 4, заголовок <QtDeclarative>.
  • если вы используете Qt 5, заголовок <QtQml>.

в конце концов, у вас должны быть такие вещи:

main.cpp (файл с функцией main () C++):

// C++ header to include for using qmlRegisterType();
#include <QtDeclarative>    // If you use Qt4
#include <QtQml>            // If you use Qt5

// Some stuff used by the main(); function
#include <QApplication>
#include <QLatin1String>

#include "ui/qtquickapplicationviewer.hpp"    // Something which manages your QML files. Qt Creator will generate it for you if you use it to code..
#include "fileio.h"    // Your FileIO C++ class

/**
 * @fn Q_DECL_EXPORT int main(int argc, char *argv[])
 * @brief The C++ main(); function. Your program begins HERE.
 */
Q_DECL_EXPORT int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    // ...

    // Declaring your C++ class to the QML system
    qmlRegisterType<FileIO>("MyCustomClasses", 1, 0, "FileIOQML");

    // ...

    // Loading your main QML file
    QLatin1String mainQMLFile = "./ui/qml/main.qml";
    QtQuickApplicationViewer viewer;
    viewer.setMainQmlFile(mainQMLFile);

    // Showing how beautiful your QML interface is :)
    viewer.showExpanded();

    // Now let's play with your QML interface is :)
    return app.exec();
}

main.QML-файл для загрузки (прямо из учебника Nokia):

import QtQuick 1.1
import MyCustomClasses 1.0

Rectangle {
    width: 360
    height: 360
    Text {
        id: myText
        text: "Hello World"
        anchors.centerIn: parent
    }

    FileIOQML {
        id: myFile
        source: "my_file.txt"
        onError: console.log(msg)
    }

    Component.onCompleted: {
        console.log( "WRITE"+ myFile.write("TEST"));
        myText.text =  myFile.read();
    }
}

NB: я изменил некоторые"FileIO " из учебника Nokia, чтобы избежать путаницы.


Если ваши файлы только текстовые, вы можете использовать XMLHttpRequest (как для чтения, так и для записи), например:

function openFile(fileUrl) {
    var request = new XMLHttpRequest();
    request.open("GET", fileUrl, false);
    request.send(null);
    return request.responseText;
}

function saveFile(fileUrl, text) {
    var request = new XMLHttpRequest();
    request.open("PUT", fileUrl, false);
    request.send(text);
    return request.status;
}

вот демонстрационное приложение (Qt 5.6):

import QtQuick 2.6
import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.5

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Demo App")

    function openFile(fileUrl) {
        var request = new XMLHttpRequest();
        request.open("GET", fileUrl, false);
        request.send(null);
        return request.responseText;
    }

    function saveFile(fileUrl, text) {
        var request = new XMLHttpRequest();
        request.open("PUT", fileUrl, false);
        request.send(text);
        return request.status;
    }

    FileDialog {
        id: openFileDialog
        nameFilters: ["Text files (*.txt)", "All files (*)"]
        onAccepted: textEdit.text = openFile(openFileDialog.fileUrl)
    }

    FileDialog {
        id: saveFileDialog
        selectExisting: false
        nameFilters: ["Text files (*.txt)", "All files (*)"]
        onAccepted: saveFile(saveFileDialog.fileUrl, textEdit.text)
    }

    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("&Open")
                onTriggered: openFileDialog.open()
            }
            MenuItem {
                text: qsTr("&Save")
                onTriggered: saveFileDialog.open()
            }
            MenuItem {
                text: qsTr("Exit")
                onTriggered: Qt.quit();
            }
        }
    }

    TextArea {
        id: textEdit
        anchors.fill: parent
        text:
            "Lorem ipsum dolor sit amet, consectetur adipisicing elit, " +
            "sed do eiusmod tempor incididunt ut labore et dolore magna " +
            "aliqua. Ut enim ad minim veniam, quis nostrud exercitation " +
            "ullamco laboris nisi ut aliquip ex ea commodo cosnsequat. ";
    }
}

P. S. Обратите внимание, что все современные браузеры будут бросать исключение безопасности, если вы будете пытаться использовать такие функции, как выше, но с QML это допускает (даже для перезаписи файла). Но не уверен, намеренно или по ошибке.


С V-Play SDK вы можете использовать пакета fileutils класс из QML, для доступа к файловой системе на любой платформе.

Это будет выглядеть так:

var success = fileUtils.writeFile("TextFiles/myFile.txt", "test text")

полный пример FileIO можно найти на этой странице:https://qmlbook.github.io/en/ch16/index.html

и исходный код можно найти здесь: https://github.com/qmlbook/qmlbook/tree/master/en/ch16/src/fileio