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. Expand all QTreeWidget items and hide all expansion indicators
Forum Updated to NodeBB v4.3 + New Features

Expand all QTreeWidget items and hide all expansion indicators

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 4.0k Views 3 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.
  • S Offline
    S Offline
    skebanga
    wrote on last edited by
    #1

    I have a sample application which displays a QTreeWidget with a number of levels, and sets them all expanded.

    Basic setup:

    The following works as expected:

    1. Create the QTreeWidget and set as central widget:

    QMainWindow* main_window = new QMainWindow();
    QTreeWidget* tree = new QTreeWidget();
    
    main_window->setCentralWidget(tree);
    

    2. Create some sample data which will be used to create the items in the tree:

    std::vector<std::vector<std::string>> fields = {
    	{ "foo" },
    	{ "bar", "baz", "fizz", "buzz" },
    	{ "apples", "oranges" }
    };
    

    3. Loop over the sample data, creating QTreeWidgetItems:

    QTreeWidgetItem* parent = nullptr;
    QTreeWidgetItem* item   = nullptr;
    
    for (auto& level : fields)
    {
    	for (auto& field : level)
    	{
    		if (!parent)
    			item = new QTreeWidgetItem(tree, { QString::fromStdString(field) });
    		else
    			item = new QTreeWidgetItem(parent, { QString::fromStdString(field) });
    
    	}
    	parent = item;
    }
    

    4. Set the header and expand all the nodes:

    tree->setHeaderLabels({ "fields" });
    tree->expandAll();
    

    This correctly populates the tree, and the resulting window looks like this:

    tree expanded

    Hide the expansion indicators

    I don't want the user to be able to collapse the nodes, so I use setchildIndicatorPolicy:

    QTreeWidgetItem* last = tree->topLevelItem(tree->topLevelItemCount() - 1);
    while(last)
    {
    	last->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicator);
    	last = last->child(last->childCount() - 1);
    }
    

    However, doing this hides all the children below the first level

    DontShowIndicator

    The documentation for QTreeWidgetItem::DontShowIndicator says

    The controls for expanding and collapsing will never be shown even if there are children. If the node is forced open the user will not be able to expand or collapse the item.

    Force the node open

    So I update the code to set the item expanded

    QTreeWidgetItem* last = tree->topLevelItem(tree->topLevelItemCount() - 1);
    while(last)
    {
    	last->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicator);
    	last->setExpanded(true);
    
    	last = last->child(last->childCount() - 1);
    }
    

    That makes no difference

    ForcedOpen

    Expanding the node before I set the ChildIndicatorPolicy doesn't work either

    QTreeWidgetItem* last = tree->topLevelItem(tree->topLevelItemCount() - 1);
    while(last)
    {
    	last->setExpanded(true);
    	last->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicator);
    
    	last = last->child(last->childCount() - 1);
    }
    

    ForcedOpenBefore

    Question:

    How can I set all my nodes expanded, and show no expansion indicators?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      That kinda looks like a bug... Did you check the bug report system ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • S Offline
        S Offline
        skebanga
        wrote on last edited by
        #3

        I found the following in the source, which definitely doesn't look correct.

        bool QTreeModel::hasChildren(const QModelIndex &parent) const
        {
            if (!parent.isValid())
                return (rootItem->childCount() > 0);
        
            QTreeWidgetItem *itm = item(parent);
            if (!itm)
                return false;
            switch (itm->d->policy) {
            case QTreeWidgetItem::ShowIndicator:
                return true;
            case QTreeWidgetItem::DontShowIndicator:
                return false;
            case QTreeWidgetItem::DontShowIndicatorWhenChildless:
                return (itm->childCount() > 0);
            }
            return false;
        }
        

        I haven't found everything which calls hasChildren, but the name of the function does stand out as making this look like it could be a bug.

        I'll report a bug

        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