user3336091
user3336091

Reputation: 17

Setting QtreeWidget Height

I am new to qt So I don't have much knowledge of sizepolicy and streches of widgets. I have a vertical box layout in which I have first added a Qlabel and then a QTreeWidget and then again a Qlabel. Now the problem is QTreeWidget is taking full space in vertical direction and then after leaving a very big space after QTreeWidget, although only rows exist currently in it, QLabel is added. I want that second Qlabel is added immediately after two rows visible and now when more rows are added then It shift downwards. Can someone suggest me how to do this?

Upvotes: 0

Views: 3913

Answers (1)

edisn
edisn

Reputation: 68

I think this is what you meant: UI has in a layout: Label, QTreeWidget, Label, Spacer (Spacer is important becaus else Qt might just expand the labels to fill the window.) Important: In Designer TreeWidget hight to preffered, vertical scrollbar off.

UI Example:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>517</width>
    <height>568</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QLabel" name="label">
      <property name="text">
       <string>TextLabel</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="my_tree" name="treeView">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="verticalScrollBarPolicy">
       <enum>Qt::ScrollBarAlwaysOff</enum>
      </property>
      <property name="horizontalScrollBarPolicy">
       <enum>Qt::ScrollBarAsNeeded</enum>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QLabel" name="label_2">
      <property name="text">
       <string>TextLabel</string>
      </property>
     </widget>
    </item>
    <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>40</height>
       </size>
      </property>
     </spacer>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>517</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <customwidgets>
  <customwidget>
   <class>my_tree</class>
   <extends>QTreeView</extends>
   <header>my_tree.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

A Overloaded QTreeView (in your case QTreeWidget) is used to get the wanted sizehints: EDIT -- This is a uggly header only definition i called my_tree.h --

    #ifndef MY_TREE_H
#define MY_TREE_H
#include <QHeaderView>
#include <QTreeView>

class my_tree: public QTreeView
{
    Q_OBJECT
public:
    my_tree(QWidget* parent):QTreeView(parent)
    {
        // Important: if something is shown/hidden we need a new size
        connect(this,SIGNAL(expanded( const QModelIndex & )),SLOT(onExpandCollapsed()));
        connect(this,SIGNAL(collapsed( const QModelIndex & )),SLOT(onExpandCollapsed()));
    };

    // QWidget interface
public:
    QSize sizeHint() const {return my_size(); };
    QSize minimumSizeHint() const { return my_size(); };

private:
    QSize my_size() const
    {   //QSize tst(sizeHintForColumn(0) + 2 * frameWidth(), sizeHintForRow(0) + 2 * frameWidth());

        int neededHight= 2 * frameWidth()+ this->header()->height();

        QModelIndex root = this->rootIndex();

        QAbstractItemModel* m = this->model();

        //if(this->rootIsDecorated())
        {
            neededHight += recursiveHeightHint(root,m);
        }
        QSize temp = QTreeView::sizeHint();
        temp.setHeight(neededHight);
        return QSize(1,neededHight);
    }

    // we need the size of all visible items -> isExpanded
    // the root item is usually shown as a non-Valid index -> !i.isValid()
    int recursiveHeightHint(QModelIndex i,QAbstractItemModel* m) const
    {
        int temp=sizeHintForIndex(i).height();
        if(this->isExpanded(i) || !i.isValid())
        {
        if(m->hasChildren(i))
        {
            int numRows = m->rowCount(i);
            for(int count =0;count<numRows;count++)
                temp+=recursiveHeightHint(m->index(count,0,i),m);
        }
        }
        return temp;
    }

private slots:
    void onExpandCollapsed(){updateGeometry();}
};

#endif // MY_TREE_H

PS: in Designer first place the base Widget and then define it as placeholder for the self designed one.

I used this entry to get to this solution:

Upvotes: 1

Related Questions