Update QTableView after hiding columns
-
Hello,
I have a question about updating QTableView after hiding some columns. The code below is an extract from my whole code.
Hopefully it shows what I am doing and help to understand my problem.There is a QSqlTableModel* myDataTableModel with the data to display in QTableView* myDataTableView.
The user's selection of columns to hide is stored in table "tableFilter".
If "bShowColumn" is 1 (One) the row should be shown. If "bShowColumn" is 0 (Zero) the row should be hidden.The tables with data representet "by strTableName could be different. They could have a different amount of columns and also different names of the columns. Nevertheless I want to show the data in the same view "myDataTableView".
All is fine when I run the code the first time.
Doing this a second time with a different table (strTableName changed) the QTableView is not updated properly and does not show all columns.What I am doing wrong?
bool hide; int index; QString strTableName; // This is just for the example. // The name of the table could change and is a parameter of the function QSqlTableModel* myDataTableModel; myDataTableModel->setTable(strTableName);-- myDataTableModel->setEditStrategy(QSqlTableModel::OnFieldChange); myDataTableModel->setHeaderData(myDataTableModel->fieldIndex("run_number"), Qt::Horizontal, "run"); myDataTableModel->select(); ui.mySimDataTableView->setModel(myDataTableModel); // Hide ID Column ui.mySimDataTableView->setColumnHidden(myDataTableModel->fieldIndex("idSimData"), true); QSqlDatabase db = QSqlDatabase::database("DEFAULT"); QSqlQuery stuff(db); QString s = "SELECT tPropName, bShowColumn FROM tableFilter"; if (stuff.exec(s)); { while(stuff.next()); { hide = stuff.value(1);.toInt() == 0; index = myDataTableModel()->fieldIndex(stuff.value(0).toString()); if(index >= 0) { ui.mySimDataTableView->setColumnHidden(index, hide); } } }
-
Why not use a proxy model (based on "QSortFilterProxyModel":http://doc.qt.nokia.com/stable/qsortfilterproxymodel.html) like in this "wiki article":http://developer.qt.nokia.com/wiki/Filter_Columns_in_a_QFileSystemModel
And don't forget to let the model emit signals (columnAdde/Remove etc.) afterwards to have the view catch up the changes.
-
you needn't emit signals if you just filter out rows. There are callback for hiding rows/columns in QSortFilterProxyModel: "filterAcceptsColumn":http://doc.qt.nokia.com/latest/qsortfilterproxymodel.html#filterAcceptsColumn and "filterAcceptsRow":http://doc.qt.nokia.com/latest/qsortfilterproxymodel.html#filterAcceptsRow
Also see the "example in the description of QSortFilterProxyModel":http://doc.qt.nokia.com/latest/qsortfilterproxymodel.html#filtering
-
Yep. But if the filter rules change after the view has finished displaying items, you must inform the view of the change. Fortunately the Trolls have provided us with slot "invalidateFilter() ":http://doc.qt.nokia.com/latest/qsortfilterproxymodel.html#invalidateFilter for this :-)
-
Ok, if I do this
// unhide all hidden columns int rows = myDataTableModel()->rowCount(); for(int i=0; i<rows; i++) { ui.mySimDataTableView->setColumnHidden(i, false); }
before
ui.mySimDataTableView->setModel(myDataTableModel);
everythink is fine.
Thank you :-)
-
[quote author="js_dev" date="1296216104"]Thanks so far.
I will have a look at the proxy model next week and will also try to unhide the hidden columns before I hide them again.[/quote]
If you use the proxy model approach, the setColumnHidden of the view is not needed anymore.
-
Ok, if I do this
// unhide all hidden columns int rows = myDataTableModel()->rowCount(); for(int i=0; i<rows; i++) { ui.mySimDataTableView->setColumnHidden(i, false); }
before
ui.mySimDataTableView->setModel(myDataTableModel);
everythink is fine.
Thank you :-)[/quote]
What is a bit strange:
you iterate over
rowCount
and callsetColumnHidden
This does not fit! -
Oh man - I mixed up rows and columns again :-(
Sorry for the confuision.It must look like this:
// unhide all hidden columns int cols = myDataTableModel()->columnCount(); for(int i=0; i<cols; i++) { ui.mySimDataTableView->setColumnHidden(i, false); } ui.mySimDataTableView->setModel(myDataTableModel());
-
I found another (maybe easier) way to unhide all the previously hidden columns.
If I resize the columns to content after hiding the columns I can get rid of the loop I posted above and the table view shows all the columns I want to see.
Do it like this:
if (stuff.exec(s)) { while(stuff.next()) { hide = stuff.value(1).toInt() == 0; index = myDataTableModel();->fieldIndex(stuff.value(0).toString()); if(index >= 0) { ui.mySimDataTableView->setColumnHidden(index, hide); } } } // This will resize the columns to content and also unhide all previously hidden columns ui.mySimDataTableView->resizeColumnsToContents();