PDA

View Full Version : Saving data from QStandardItemModel to harddrive



Ferric
18th January 2010, 20:46
Hi,

I have a QTableView (please see attached) that is set with a QStandardItemModel, its all working properly, and now I would like to try and save the data in the "model" to the harddrive.

Im pretty new to Qt and not really sure where to begin, I imagine I would set up a button as a signal and attach this to some kind of "save dialog" slot, but I'm not really sure... also does the model data have to be saved in a specific format?


Thanks

ChrisW67
18th January 2010, 23:53
You can save the data any way you like. For a simple approach you could iterate over the rows and columns of the model and write to a QDataStream something like:

QFile file(filename);
QDataStream out(&file);
out << quint32(MagicNumber); // lets you verify the file type/version on read
for (int row = 0; row < model.rowCount(); row++ ) {
for (int col = 0; col < model.columnCount(); col++) {
// do something to fetch the item data
out << quint16(row) << quint16(col) << relevant bits of the data;
}
}

Coises
19th January 2010, 01:26
Im pretty new to Qt and not really sure where to begin, I imagine I would set up a button as a signal and attach this to some kind of "save dialog" slot, but I'm not really sure... also does the model data have to be saved in a specific format?

Setting up a button and using its QAbstractButton::clicked signal to detect when it is pushed is correct, but you connect that signal to a slot that you will add to your main window class. In that slot, you will do whatever you need to save the data, which might include calling QFileDialog::getSaveFileName to get a file name and location from the user to which to save.

As far as I can see, the Qt model classes don’t provide any “serialization” of their own, so it will be up to your code to traverse the model in such a way that you write out both the data needed to reconstruct each QStandardItem and whatever information you need to add them to the model in the correct places (that is, that you can figure out the row and column — and parent, when a tree structure is used — of each data item when you read it back). Since the data store for each item in a QStandardItemModel is a QStandardItem, there is an easy way to write and read the data for each item, using QStandardItem::write and QStandardItem::read.

These functions are not likely to be the most efficient in either time or space, but they provide a simple, general method that should be practical for small tables. For large data structures, you probably wouldn’t be using QStandardItem and QStandardItemModel anyway; you’d subclass QAbstractItemModel and design a custom backing store. In that case you would also have to work out a custom method of reading and writing the backing store.

Ferric
19th January 2010, 23:15
Hi,

Thanks for the replies, I have the following code working well,


void Loader::saveToFile()
{
QString fileName = QFileDialog::getSaveFileName( this, tr("Save File As..."), QDir::homePath(), tr("txt (*.txt)"));
if (fileName.isEmpty())
return;
else
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
QMessageBox::information(this, tr("Unable to open file"), file.errorString());
return;
}
// Need to find a way to clear all present data in file, if the file already exists.
QDataStream out(&file);
out.setVersion(QDataStream::Qt_4_3);
out << channels; // "channels" is a QMap<QString, QString> which has the relevant information already inserted.
}
}


The problem I now have is that if I open a file that already exists, I overwrite my data to this file, but any original data that is not overwritten still remains... what I need is a way to delete all original data in the file before I write my new data.

Is there a simple way to delete all data in a file?

Thanks

ChrisW67
20th January 2010, 01:04
QFile::resize() could be what you are looking for. Set the size to zero before writing (or you could try to set the size to QFile::pos() at the end of writing). Alternately, test for the existence of the file and use QFile::remove() before opening.

Ferric
20th January 2010, 01:17
The code below works perfectly, cheers!


file.resize(0);

ChrisW67
20th January 2010, 04:16
Had a bit of a D'oh! moment... you could open with "QFile::WriteOnly | QFile::Truncate" in the first place.