Pergunta

What is the easiest way to save and load data to and from a file using Qt?

Could you please provide an example how to do this?

Foi útil?

Solução

You could create a public slot for writing which would be called in your QML signal handler.

Then, you could create either a Q_INVOKABLE method for reading with the data returned or a slot for reading with void return value. In that latter case, you could have a data property which is mapped to the desired property if that is the use case.

Overall, the right solution depends on more context which has not been provided yet.

The class needs to contain the Q_OBJECT macro and it needs to inherit the QObject class due to the signal-slot mechanism and the fact that the QML engine is built around QObjects at this point of time, unfortunately. That may change in the future, hopefully.

myclass.h

class MyClass : public QObject
{
    Q_OBJECT
    // Leaving this behind comment since I would not start off with this.
    // Still, it might be interesting for your use case.
    // Q_PROPERTY(QByteArray data READ data WRITE setData NOTIFY dataChanged)
    public:
        MyClass() {} // Dummy for now because it is not the point
        ~MyClass() {} // Dummy for now because it is not the point

   Q_INVOKABLE QByteArray read();
   QByteArray data() const ;

   public slots:
       // void read(); // This would read into the internal variable  for instance
       void write(QByteArray data) const;

   // private:
       // QByteArray m_data;
};

myclass.cpp

/* 
void MyClass::read()
{
    QFile file("in.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    QTextStream in(&file);
    // You could also use the readAll() method in here.
    // Although be careful for huge files due to memory constraints
    while (!in.atEnd()) {
        QString line = in.readLine();
        m_data.append(line);
    }
}
*/

QByteArray MyClass::read()
{
    QByteArray data;
    QFile file("in.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    QTextStream in(&file);
    // You could use readAll() here, too.
    while (!in.atEnd()) {
        QString line = in.readLine();
        data.append(line);
    }

    file.close();
    return data;
}

void MyClass::write(QByteArray data)
{
    QFile file("out.txt");
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return;

    QTextStream out(&file);
    out.write(data);
    file.close();
}

Once that is done, you could expose this functionality to QML in the following way:

main.cpp

...
MyClass *myClass = new MyClass();
viewContext->setContextProperty("MyClass", myClass);
...

Then you could call these functions from QML as follows:

main.qml

...
Page {
    Button {
        text: "Read"
        onClicked: readLabel.text = myClass.read()
    }

    Label {
        id: readLabel
    }

    Button {
        text: "Write"
        onClicked: myClass.write()
    }
}
...

Disclaimer: I was writing this code like a raw text, so it may not compile, it may eat babies, et al, but it should demonstrate the idea behind. In the end, you would have two buttons for the read and write operations, and one label displaying the file content read.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top