设置 QtreeWidget 高度

Posted

技术标签:

【中文标题】设置 QtreeWidget 高度【英文标题】:Setting QtreeWidget Height 【发布时间】:2015-04-14 02:35:17 【问题描述】:

我是 qt 的新手,所以我对 sizepolicy 和小部件的延伸了解不多。 我有一个垂直框布局,我首先添加了一个 Qlabel,然后是一个 QTreeWidget,然后又是一个 Qlabel。现在的问题是 QTreeWidget 在垂直方向上占据了全部空间,然后在 QTreeWidget 之后留下了一个很大的空间之后,虽然目前只有行存在,但添加了 QLabel。我希望在可见的两行之后立即添加第二个 Qlabel,现在当添加更多行时,它会向下移动。有人可以建议我怎么做吗?

【问题讨论】:

【参考方案1】:

我想这就是你的意思: UI 有一个布局:Label、QTreeWidget、Label、Spacer (Spacer 很重要,因为否则 Qt 可能只是扩展标签以填充窗口。) 重要提示:在 Designer TreeWidget hight to preffered,垂直滚动条关闭。

用户界面示例:

<?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>

重载的 QTreeView(在您的情况下为 QTreeWidget)用于获取所需的大小提示: 编辑——这是我称之为 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:在 Designer 中首先放置基础 Widget,然后将其定义为自行设计的占位符。

我使用这个条目来获得这个解决方案:

QListWidget adjust size to content

【讨论】:

感谢@edisn 的评论。我会检查一下,如果这对我有用,我会告诉你。 你能告诉我为什么qsize的宽度,当我们在my_size()中返回它时,是1? 这对我有用。谢谢你。这里只有一个问题是,当我从 qtreewidget 中删除任何项目时,qtreewidget 下面的标签不会向上移动它会停留在同一个地方。知道为什么会这样吗? 1) 在我的示例中,我不需要 widht,因此我只是添加了一个 1. 替代返回 temp 元素。 (我在两个解决方案之间。) 2)sizehint 由 updateGeometry() 使用,我只在折叠或展开时调用它,添加一些其他信号以更改模型,它会起作用。例如'connect(this,SIGNAL(insertRow(int)),SLOT(onExpandCollapsed()));'

以上是关于设置 QtreeWidget 高度的主要内容,如果未能解决你的问题,请参考以下文章

QT如何设置QTreeWidget行高?

调整 QTreeWidget 内的小部件大小(使用 setItemWidget 设置)?

如何使用 QStyledItemDelegate 在 QTreeWidget 中拥有不同高度的 QTreeWidgetItems?

QTreeWidget:如何动态更改 sizeHint?

在qtreewidgetitem中data函数怎么用

QTreeWidget - 重新计算每行内容的行高?