调整大小时如何使 QTreeWidget 调用 sizeHint?

Posted

技术标签:

【中文标题】调整大小时如何使 QTreeWidget 调用 sizeHint?【英文标题】:How to make QTreeWidget call sizeHint when resized? 【发布时间】:2021-07-04 16:04:59 【问题描述】:

我正在使用自定义QStyledItemDelegate 以在QTreeWidget 中显示数据。因此我实现了paint()sizeHint() 函数。

这幅画效果很好,但我对sizeHint 有一些问题。问题是如果水平空间不足以显示不换行,我将显示一些将换行的文本。问题是当QTreeWidget 被调整大小时,Qt 似乎没有调用sizeHint 函数。在这些情况下,只有 paint 函数会被调用,但是当我的项目更改它们的行高(取决于它们是否换行以及换行的频率)时,这会导致树的布局变得混乱。

目前的情况是:布局在小部件创建后立即按预期工作,只要不调整大小,一切都像魅力一样工作。但是,如果要调整小部件的大小,则文本开始或停止换行,更改项目的高度(这一切都在仍然定期调用的paint 函数中完成),然后树的垂直布局被破坏(要么项目以很大的距离间隔开或开始重叠,具体取决于项目现在是占用更少还是更多的垂直空间来渲染)。

我尝试在树小部件上将uniformHeights 明确设置为falsewordWraptrue,但这似乎没有任何效果。

这是一个示例sizeHint 函数:

QSize MyItemDelegate::sizeHint(const QStyleOptionViewItem &inOption, const QModelIndex &index) 
    QStyleOptionView option = inOption;
    initStyleOption(option);

    QTextDocumentOptioon opt;
    opt.setWrapMode(Qt::WrapAtWordBoundaryOrAnywhere);
    opt.setAlignment(Qt::AlignLeft)

    QTextDocument doc;
    doc.setDefaultTextOption(opt);
    doc.setTextWidth(option.widget->size().width());
    doc.sethtml("An example text that may or may not wrap");

    return doc.size();

如何让树小部件调用项目委托的 sizeHint 函数以更频繁地调用(在所有调整大小事件上)?

【问题讨论】:

所有调整大小事件 为了让它不那么神秘:重新实现ResizeEvent并手动调用repaint @scopchanov repaint 是否也重新计算布局?从名字看来,它只会重绘现有的按钮...... 了解这一点的一种方法是尝试一下。 我刚刚对此进行了测试,似乎正如我所说:repaint(和update就此而言)只会导致重新绘制,但不会重新计算项目的大小。 【参考方案1】:

这个答案的部分灵感来自scopchanov 的 cmets - 谢谢!

为了让树部件更新其布局,我必须首先继承QTreeWidget,然后覆盖QTreeWidget::resizeEvent。这样我就得到了一个钩子,每次调整小部件的大小时,我都可以在其中注入代码。

为了让小部件真正更新其布局,我使用QAbstractItemView::scheduleDelayedItemsLayoutQAbstracTItemView::executeDelayedItemsLayout 应该也可以)。

因此我的resizeEvent 函数看起来像这样:

void MyCustomTree::resizeEvent(QResizeEvent *event) 
    scheduleDelayedItemsLayout();

    QTreeWidget::resizeEvent(event);

参考:

https://doc.qt.io/qt-5/qabstractitemview.html#executeDelayedItemsLayout https://doc.qt.io/qt-5/qabstractitemview.html#scheduleDelayedItemsLayout

【讨论】:

所以,基本上我说得对,你有解决问题的关键,即在所有调整大小事件上,在你的问题结束时。 ;) 很高兴它成功了! @scopchanov 是的。再次感谢! :)

以上是关于调整大小时如何使 QTreeWidget 调用 sizeHint?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QTreeWidget 中设置小列宽?

如何在 QTreeWidget/QTreeView 中获取行高

调整单元格大小时如何使表格视图动画平滑

调整浏览器大小时,如何使部分中的对象保持居中?

当调整大小小于元素时,如何使元素隐藏在 UIView 中

MFC如何使控件大小随着对话框大小自动调整