[Solved] 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);
    }
    }
    }
    @



  • 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.



  • 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 :-)



  • 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.



  • 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.



  • [quote author="js_dev" date="1296216939"]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 call setColumnHidden
    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();
    @



  • As this is not a described behavior, you should take care that it might change in future...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.