Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Resizing QTreeView behind a QWidgetAction



  • Hi,

    I have a QToolButton that when pressed should open a QTreeView as a kind of drop-down menu (I don't want to use QMenu with submenues for various reasons). I use a custom class derived from QWidgetAction with the QTreeView as the QWidgetAction's defaultWidget.

    However, I want the QTreeView "popup" to resize to fit the content: If all top-level items are collapsed, it should have the minimum height that doesn't require scroll areas. As the user expands items, it should grow appropriately until a certain maximum is reached, at which point it uses scroll areas instead.

    The furthest I got so far is this:

    TagSelectWidgetAction::TagSelectWidgetAction(QObject* parent)
            : QWidgetAction(parent)
    {
        m_view = new TagSelectItemView; // TagSelectItemView inherits from QTreeView (you can assume it's a standard QTreeView)
    
        connect(m_view, SIGNAL(expanded(const QModelIndex&)), this, SLOT(viewExpanded(const QModelIndex&)));
    
        m_view->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
    
        setDefaultWidget(m_view);
    }
    
    TagSelectItemView* TagSelectWidgetAction::view()
    {
        return m_view;
    }
    
    void TagSelectWidgetAction::viewExpanded(const QModelIndex& idx)
    {
        m_view->adjustSize();
    }
    

    This is still missing the maximum size constraint. The problem is that this does not do anything when the user expands a node. AdjustToContents only does the resizing once I click the QToolButton twice to hide and re-show the QTreeView. That's why I tried calling adjustSize() as soon as the user expands a node. With adjustSize(), it does seem like something tries to resize but there is some sort of bounding box around the popup that just cuts everything below the old height off: I can see the border on the bottom vanish but the actual popup doesn't get any larger.

    I have tried various combinations of updateGeometry(), update(), adjustSize() and sending a QResizeEvent manually, on both m_view as well as its viewport and parent widget. I have even called hide() and show() manually to simulate "clicking twice" on the QToolButton. The same thing happens in all those cases.

    Does anybody have an idea what's happening here and how I can get resizing behavior similar to what I want?

    In case it matters, here's how I create the QToolButton and TagSelectWidgetAction:

    m_tagSelectWidgetAction = new TagSelectWidgetAction(this);
    connect(m_tagSelectWidgetAction->view(), SIGNAL(tagSelectionChanged(const QString&, bool)),
            this, SLOT(tagSelectionChangedSlot(const QString&, bool)));
    connect(m_tagSelectWidgetAction, SIGNAL(triggered(bool)),
            this, SLOT(updateTagsMenu()));
    
    m_tagsSelector = new QToolButton(this);
    m_tagsSelector->setIcon(QIcon::fromTheme(QStringLiteral("tag")));
    m_tagsSelector->addAction(m_tagSelectWidgetAction);
    m_tagsSelector->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
    m_tagsSelector->setPopupMode(QToolButton::MenuButtonPopup);
    m_tagsSelector->setAutoRaise(true);
    

Log in to reply