Update QTableView after hiding columns
-
wrote on 28 Jan 2011, 10:14 last edited by VRonin
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); } } }
-
wrote on 28 Jan 2011, 11:20 last edited by
First of all,m you hide columns, not rows :-)
I think, the problem is that you explicitly hide columns, and the perhaps switch the model. You should remove the setColumnHidden and rehide all new hidden rows.
I think, that could help.
-
wrote on 28 Jan 2011, 11:28 last edited by
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.
-
wrote on 28 Jan 2011, 11:42 last edited by
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
-
wrote on 28 Jan 2011, 12:00 last edited by
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 :-)
-
wrote on 28 Jan 2011, 12:01 last edited by
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.
-
wrote on 28 Jan 2011, 12:15 last edited by VRonin
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 :-)
-
wrote on 28 Jan 2011, 13:03 last edited by
[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.
-
wrote on 28 Jan 2011, 13:04 last edited by VRonin
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! -
wrote on 31 Jan 2011, 06:59 last edited by VRonin
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());
-
wrote on 1 Feb 2011, 07:02 last edited by VRonin
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();
-
wrote on 1 Feb 2011, 08:45 last edited by
As this is not a described behavior, you should take care that it might change in future...
1/12