2013-07-26 4 views
7

Próbuję zaimplementować Reading and writing files in QML i natknąłem się na połączony artykuł firmy Nokia, ale nie udało się z powodzeniem użyć pozornie oczywistego przykładu kodu. Myślę, że nie muszę mówić, że jestem totalną nowicjuszką w tej dziedzinie.Odczytywanie i zapisywanie plików w QML (Qt)

Gdzie mam umieścić ten fragment kodu (który jest drugim fragment kodu na stronie .):

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

ja również zachować uzyskiwanie błąd w odniesieniu do nie qmlRegisterType jest zarejestrowany w kontekście kiedy umieść powyższy fragment kodu w moim głównym formularzu. Czy ktoś może zaoferować porady dotyczące sposobu wdrożenia tego (lub jakiejkolwiek metody odczytu i zapisu plików w QML/Qt)?

+1

To zdecydowanie coś zrobić w C++. Zachowaj QML cienką warstwę interfejsu użytkownika, która powinna być. –

+1

Frank, dzięki za odpowiedź. Właściwie kod w linku jest implementacją dostępu do plików w C++ i moje pytanie brzmi: jak to zrobić (ponownie w C++)? – Nepaluz

+0

Jak nazywasz swoją "główną formę"? – alexisdm

Odpowiedz

7

Przykład napisany przez Nokię w samouczku nie jest czystym programem QML. Zawiera zarówno C++, jak i QML. Ten rodzaj programu jest zwykle programem C++, który ładuje plik QML i renderuje go. Programy w C++ zwykle zaczynają się od funkcji o nazwie int main(int argc, char *argv[]);. W twoim przypadku jest to funkcja "main()", która ładuje twój główny plik QML (main.qml) i wyświetla go.

Ale przed załadowaniem głównego pliku QML, musisz poinformować system QML, że użyjesz niestandardowej klasy QML o nazwie FileIO. W tym celu będziesz musiał użyć funkcji C++ int qmlRegisterType<T>(const char * package, int majorVersion, int minorVersion, char * classNameInQML);. To trwa około 5 parametrów:

  • T: C++ parametr szablonu. To jest twoja klasa C++ (FileIO).
  • pakiet: wszystkie klasy QML są w pakiecie, które są wersjonowane. To jest nazwa pakietu.
  • majorVersion: wszystkie klasy QML są w pakiecie, które są wersjonowane. To jest główny numer wersji pakietu.
  • minorVersion: wszystkie klasy QML są w pakiecie, które są wersjonowane. Jest to mniejszy numer wersji pakietu.
  • classNameInQML: wszystkie klasy QML znajdują się w pakiecie, który jest wersjonowany. Jest to nazwa klasy, której będziesz używać w plikach QML. W większości przypadków nazwa jest taka sama jak nazwa klasy C++.

Do korzystania z tej funkcji, trzeba zawierać nagłówek C++ w pliku C++, gdzie piszesz go:

  • Jeśli używasz Qt 4, nagłówek jest <QtDeclarative>.
  • Jeśli używasz Qt 5, nagłówek to <QtQml>.

W końcu trzeba mieć pewne rzeczy tak:

main.cpp (plik z głównym() C++) funkcji:

// 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(); 
} 

główne.Plik QML załadować (po prawej od samouczka 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: Zmieniłem trochę „FileIO” z samouczka Nokia w celu uniknięcia nieporozumień.

+0

air-dex - dziękuję za to. Samouczek, jak mniemam, był przeznaczony dla doświadczonych programistów, nigdy nie był jasny o parametrach qmlRegisterType , a to całkowicie mnie potknęło! Ale jak podejrzewałem, okazuje się, że to po prostu taka prosta rzecz. Jeszcze raz dziękuję, tracił nadzieję na stackoverflow! – Nepaluz

10

Jeśli pliki jest tylko tekst, można użyć XMLHttpRequest (zarówno dla czytania i pisania), tak:

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; 
} 

Oto aplikacja demo (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. "; 
    } 
} 

PS: Zauważ, że wszystkie współczesne przeglądarki wyrzucą wyjątek bezpieczeństwa, jeśli spróbujesz użyć funkcji takich jak wyżej, ale QML na to zezwala (nawet w przypadku przepisywania plików). Nie jest to jednak pewne z powodu projektu czy błędu.

+0

Cudowny i prawy hack. Miły :) – Phrogz