0
votes

I'm writing an app that reads and shows data from web server in QTableView/QTableWidget. Each entry will have several columns and also SetData to hold hidden information (from UI) in each entry (QVariant).

Point is, content of QTableView/QTableWidget changes based on what user choose from a ListBox, so everytime ListBox choice changes, all entries inQTableView/QTableWidget will be cleared and items related to it will be shown.

I want to cache all entries of Listbox items user click, so if user return back to same item, just show previous entries in QTableView/QTableWidget without again sending request to webserver to get content.

What's the best way to cache data to show in QTableView/QTableWidget?

1) Using QTableView and dynamically creating QAbstractTableModel, then keeping QAbstractTableModels in an array. So everytime user changes item in Listbox, I'll just call setModel on related TableModel item. Is it possible? If so how?

2) Using QTableWidget, then using something like hashmap to store all data for each listbox choice, then when user switches between items, clear QTableWidget and loop through map and add items each time?

1
First is good, and if you want get good performance then QTableWidget is not right choise. But what exactly you need,you can't create a few models and set proper model when some signal firing? - Kosovan
@Chernobyl, models should be dynamic, because Listbox content, amount of entries in Listbox and TableView will differ per user, so it should be dynamic, so what's your idea for dynamic TableModel items array? Can you show me sample code or give me a little explanation on that? - user3404070
Another way to do it would be to have one model with all data in. Which internal data block that is presented is depending on what the user has selected. In fact I think this is more "normal" than changing model for a view. - user2672165

1 Answers

2
votes

In Qt model/view framework we can use polymorphism. What does it mean? We can easily use some container to store pointer to base class (QAbstractItemModel in our case) and use this container everywhere in program to get model or get data or setData and so on. In my example I used QVector:

QVector<QAbstractItemModel*> mdlVec;//in header (private section)

Create different models and populate these models with data, but append pointer to our vector:

 QStandardItemModel *ListModel = new QStandardItemModel;
 QStandardItem *its = new QStandardItem("just example");
 ListModel->setItem(0,its);
 mdlVec.append(ListModel);
 //...
 QDir dir("G:/2");
 QStringList dirContents = dir.entryList(QStringList(), QDir::Files);
 QStringListModel *mdl = new QStringListModel(dirContents,this);
 mdlVec.append(mdl);
 //and so on

Next we create slot which connected to some signal which allows us to know which row is current now (currentRowChanged in QListWidget for example):

void MainWindow::on_listWidget_currentRowChanged(int currentRow)
{
    if(currentRow <= mdlVec.size())
        ui->tableView->setModel(mdlVec.at(currentRow));
}

We can easily set new data and do another things with models. One more example:

if(currentRow <= mdlVec.size())
{
    QAbstractItemModel *tmp = mdlVec.at(currentRow);
    tmp->setData(tmp->index(0,0),QString("%1 was changed").arg(currentRow+1));
    ui->tableView->setModel(mdlVec.at(currentRow));
}