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?
Forum Updated to NodeBB v4.3 + New Features

How do you save and restore the state of QTreeView?

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 2.2k 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 Offline
      JonBJ Offline
      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