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

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

【问题讨论】:

    标签: qt qtreewidget 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,然后将其定义为自行设计的占位符。

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

    【讨论】:

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