Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How do you save and restore the state of QTreeView?

How do you save and restore the state of QTreeView?

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 2.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    deleted385
    wrote on last edited by
    #1

    It does this by default:

    x1.gif

    Initially, I'd one table TestTable and the QTreeView was expanded. When I added the NewTable, it collapsed. I expanded it again and executed 3 more statements and it collapsed again. Then I expanded some nodes and executed rollback and it collapsed! That, probably, is because I remove all rows and add new nodes. When I execute statement(s), this function is called:

    void ObjectsView::onNoSelect(const QString &query){
        bool isDDL = query.toUpper().contains("CREATE") || query.contains("ALTER") || query.contains("DROP");
        if(!isDDL) return;
        this->query->clear();
        this->query->prepare("SELECT * FROM sqlite_master");
        this->query->exec();
        makeTree();
    }
    

    and the makeTree removes all rows and add new like this:

    void ObjectsView::makeTree()
    {
        QStandardItemModel *model;
        if(tree->model()){
            tree->model()->removeRows(0, tree->model()->rowCount());
            model = qobject_cast<QStandardItemModel*>(tree->model());
        }
        else{
            model = new QStandardItemModel(tree);
            model->setColumnCount(2);
            tree->setModel(model);
            tree->header()->setSectionResizeMode(0, QHeaderView::Stretch);
        }
        QStandardItem *rootNode;
        while (query->next()) {
           ...
            auto child = new QStandardItem(text);
            rootNode->appendRow(child);
            ...
        }
        // here in another foreach loop I add nodes in child node.
    }
    

    How to save the states of previous tree and apply those states in new tree? Names that are common in both old and new tree, I want those to get the state (expanded/collapsed) from previous tree.

    JonBJ 1 Reply Last reply
    0
    • D deleted385

      It does this by default:

      x1.gif

      Initially, I'd one table TestTable and the QTreeView was expanded. When I added the NewTable, it collapsed. I expanded it again and executed 3 more statements and it collapsed again. Then I expanded some nodes and executed rollback and it collapsed! That, probably, is because I remove all rows and add new nodes. When I execute statement(s), this function is called:

      void ObjectsView::onNoSelect(const QString &query){
          bool isDDL = query.toUpper().contains("CREATE") || query.contains("ALTER") || query.contains("DROP");
          if(!isDDL) return;
          this->query->clear();
          this->query->prepare("SELECT * FROM sqlite_master");
          this->query->exec();
          makeTree();
      }
      

      and the makeTree removes all rows and add new like this:

      void ObjectsView::makeTree()
      {
          QStandardItemModel *model;
          if(tree->model()){
              tree->model()->removeRows(0, tree->model()->rowCount());
              model = qobject_cast<QStandardItemModel*>(tree->model());
          }
          else{
              model = new QStandardItemModel(tree);
              model->setColumnCount(2);
              tree->setModel(model);
              tree->header()->setSectionResizeMode(0, QHeaderView::Stretch);
          }
          QStandardItem *rootNode;
          while (query->next()) {
             ...
              auto child = new QStandardItem(text);
              rootNode->appendRow(child);
              ...
          }
          // here in another foreach loop I add nodes in child node.
      }
      

      How to save the states of previous tree and apply those states in new tree? Names that are common in both old and new tree, I want those to get the state (expanded/collapsed) from previous tree.

      JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by JonB
      #2

      @Emon-Haque
      QTreeView, like other widgets, are not amenable to "serializing"/saving. It is normal to save the state of the model it is using, and restore that.

      Since I think that, say, the expanded/contracted state is a QTreeView-only thing, not in the model, you would need to traverse the current tree saving whatever for all of those and then re-apply as appropriate to nodes in the new tree.

      You can get further information by Googling qtreeview save state. Note e.g. https://forum.qt.io/topic/58592/saving-expanded-state-of-qtreeview/2, where our @Chris-Kawa mentions:

      One way to approach the problem would be to keep expansion state as part of your model data under a custom role. You would then implement in your model setData() for that role to store the state and data() to retrieve it and query/apply whenever you need to.

      See also https://stackoverflow.com/questions/3253301/howto-restore-qtreeview-last-expanded-state for a more detailed discussion, and perhaps some recursive code which would show you what needs doing/help you.

      D 1 Reply Last reply
      2
      • JonBJ JonB

        @Emon-Haque
        QTreeView, like other widgets, are not amenable to "serializing"/saving. It is normal to save the state of the model it is using, and restore that.

        Since I think that, say, the expanded/contracted state is a QTreeView-only thing, not in the model, you would need to traverse the current tree saving whatever for all of those and then re-apply as appropriate to nodes in the new tree.

        You can get further information by Googling qtreeview save state. Note e.g. https://forum.qt.io/topic/58592/saving-expanded-state-of-qtreeview/2, where our @Chris-Kawa mentions:

        One way to approach the problem would be to keep expansion state as part of your model data under a custom role. You would then implement in your model setData() for that role to store the state and data() to retrieve it and query/apply whenever you need to.

        See also https://stackoverflow.com/questions/3253301/howto-restore-qtreeview-last-expanded-state for a more detailed discussion, and perhaps some recursive code which would show you what needs doing/help you.

        D Offline
        D Offline
        deleted385
        wrote on last edited by deleted385
        #3

        @JonB, look at that:

        void ObjectsView::makeTree()
        {
            QStandardItemModel *model;
            QMap<QString, QStringList*> expanded;
            if(tree->model()){
                for (int row = 0; row < tree->model()->rowCount(); row++) {
                    auto index = tree->model()->index(row, 0);
                    if(!tree->isExpanded(index)) continue;
                    auto node = tree->model()->data(index).toString();
                    auto trimmed = node.left(node.indexOf(' '));
                    auto list = new QStringList;
                    expanded.insert(trimmed, list);
                    for (int child = 0; child < tree->model()->rowCount(index); child++) {
                        auto childIndex = tree->model()->index(child, 0, index);
                        if(!tree->isExpanded(childIndex)) continue;
                        node = tree->model()->data(childIndex).toString();
                        trimmed = node.left(node.indexOf(' '));
                        list->append(trimmed);
                    }
                }
                tree->model()->removeRows(0, tree->model()->rowCount());
                model = qobject_cast<QStandardItemModel*>(tree->model());
            }
            ....
            // rest of the code
            ....
            for (int row = 0; row < tree->model()->rowCount(); row++) {
                auto index = tree->model()->index(row, 0);
                auto node = tree->model()->data(index).toString();
                auto trimmed = node.left(node.indexOf(' '));
                if(!expanded.keys().contains(trimmed)) continue;
                tree->setExpanded(index, true);
                if(expanded.value(trimmed)->size()){
                    auto list = expanded.value(trimmed);
                    for (int child = 0; child < tree->model()->rowCount(index); child++) {
                        auto childIndex = tree->model()->index(child, 0, index);
                        node = tree->model()->data(childIndex).toString();
                        trimmed = node.left(node.indexOf(' '));
                        if(list->contains(trimmed)) tree->setExpanded(childIndex, true);
                    }
                }
            }
            qDeleteAll(expanded.values());
        }
        

        and somehow it works:

        x2.gif

        Any suggestion for improvement?

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved