【问题标题】:QTreeView Horizontal Scrollbar problemsQTreeView 水平滚动条问题
【发布时间】:2017-09-07 16:57:56
【问题描述】:

我的 QTreeView 水平滚动条有问题,它没有出现。我已将水平滚动条策略设置为 ScrollBarAsNeeded,但如果需要它不会出现。已尝试将展开和折叠的信号连接到插槽:

connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(update_scroll_area(QModelIndex)));
connect(this, SIGNAL(collapsed(QModelIndex)), this, SLOT(update_scroll_area(QModelIndex)));

槽由一行代码组成:

update_scroll_area(const QModelIndex& i)
{
    resizeColumnToContents(i.column());
}

这使滚动条起作用,但仅在我展开/折叠树视图项时。

我需要“每次”都有工作水平滚动条,从启动应用程序到结束。如何组织?

谢谢。

【问题讨论】:

    标签: qt horizontal-scrolling qtreeview


    【解决方案1】:

    This FAQ entry 可能会有所帮助。

    简而言之:

    • 设置水平标题以根据列的内容调整大小(即使标题隐藏也适用)
    • 禁用“stretchLastHeaderSection”属性以防止水平标题自动调整到视口的宽度(这似乎覆盖了上述设置以调整到列的大小)

    【讨论】:

    • 只有在“resize to content”和“stretchLastHeaderSection”方法之前调用“setModel”才有效。
    【解决方案2】:

    如果你使用 QT5,试试这个让 treewidget “水平”自动滚动:

    • 禁用水平标题的headerStretchLastSection。 和
    • ui->treeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);

    【讨论】:

      【解决方案3】:

      对我有用的是:

      • horizontalScrollBarPolicy 属性设置为ScrollBarAsNeeded
      • 将水平标题的headerMinimumSectionSize 属性设置为与“几何宽度”值相同的值。
      • 将水平标题的headerDefaultSectionSize 属性设置为headerMinimumSectionSize 值的两倍左右。
      • 禁用水平标题的headerStretchLastSection 属性(如其他地方所述)。

      我在我正在修改的表单上使用 Qt Designer 完成了这项工作。

      【讨论】:

        【解决方案4】:

        在我看来,默认的QTreeWidget 使用后缀椭圆(即“...”)截断树项而不是显示水平滚动条的行为是疯狂的、无用的,并且永远不会任何人想要的。但这就是我们得到的。

        以下特定于 PySide2 的 QTreeWidget 子类以列感知的方式智能地解决了这一缺陷,并扩展到当前树中的列数:

        from PySide2.QtWidgets import QHeaderView, QTreeWidget
        
        class QScrollableTreeWidget(QTreeWidget):
            '''
            :mod:`QTreeWidget`-based widget marginally improving upon the stock
            :mod:`QTreeWidget` functionality.
        
            This application-specific widget augments the stock :class:`QTreeWidget`
            with additional support for horizontal scrollbars, automatically displaying
            horizontal scrollbars for all columns whose content exceeds that column's
            width. For unknown reasons, the stock :class:`QTreeWidget` intentionally
            omits this functionality.
            '''
        
            def __init__(self, *args, **kwargs) -> None:
                super().__init__(*args, **kwargs)
        
                # Header view for this tree.
                header_view = self.header()
        
                # To display a horizontal scrollbar instead of an ellipse when resizing
                # a column smaller than its content, resize that column's section to its
                # optimal size. For further details, see the following FAQ entry:
                #     https://wiki.qt.io/Technical_FAQ#How_can_I_ensure_that_a_horizontal_scrollbar_and_not_an_ellipse_shows_up_when_resizing_a_column_smaller_than_its_content_in_a_QTreeView_.3F
                header_view.setSectionResizeMode(QHeaderView.ResizeToContents)
        
                # By default, all trees contain only one column. Under the safe
                # assumption this tree will continue to contain only one column, prevent
                # this column's content from automatically resizing to the width of the
                # viewport rather than this column's section (as requested by the prior
                # call). This unfortunate default overrides that request.
                header_view.setStretchLastSection(False)
        
            def setColumnCount(self, column_count: int) -> None:
                super().setColumnCount(column_count)
        
                # If this tree now contains more than one column, permit the last such
                # column's content to automatically resize to the width of the viewport.
                if column_count != 1:
                    self.header().setStretchLastSection(True)
        

        理论上,这个实现应该可以轻松地重写为 PyQt5 和 C++。因为 Qt 应该比明显的愚蠢默认值更好。

        【讨论】:

          【解决方案5】:

          我刚刚发现了另一种情况,即水平滚动条不会出现在自定义 treeView 类中。那是当您将“setHeaderHidden()”设置为 true 并且不覆盖 resizeEvent() 时。这正是发生在我身上的事情,我通过调用插槽 resizeColumnToContents(0) 来覆盖 resizeEvent(),因为我的自定义树视图类中只有一列可以使水平滚动条工作。

          认为这可能对某些人有所帮助。

          【讨论】:

            猜你喜欢
            • 2011-07-29
            • 1970-01-01
            • 2023-03-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-03-23
            • 2014-02-10
            相关资源
            最近更新 更多