我使用自定义QStyledItemDelegate
来在QTreeWidget
中显示数据。因此,我实现了paint()
和sizeHint()
的功能。
这幅画画得很好,但我对sizeHint
有一些问题。问题是,如果水平空间不足以在不换行的情况下显示,我将显示一些将换行的文本。问题是,当调整QTreeWidget
的大小时,Qt似乎没有调用sizeHint
函数。在这种情况下,只有paint
函数会被调用,但当我的项目更改它们的行高(取决于它们是否换行以及换行的频率(时,这会导致树的布局变得混乱。
目前的情况是:在小部件创建后,布局就如预期一样工作,只要不调整大小,一切都像魅力一样。然而,如果要调整小部件的大小,文本会开始或停止换行,更改项目的高度(这一切都是在paint
函数中完成的,该函数仍然定期调用(,然后树的垂直布局就会被破坏(项目要么间隔开很长的距离,要么开始重叠,这取决于项目现在是占用更少还是更多的垂直空间来渲染(。
我曾尝试在树小部件上显式地将uniformHeights
设置为false
,将wordWrap
设置为true
,但这似乎没有任何效果。
这是一个示例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
函数(在所有调整大小事件中(?
这个答案的部分灵感来自scopechanov的评论-谢谢!
为了让树小部件更新它的布局,我必须首先子类QTreeWidget
,然后覆盖QTreeWidget::resizeEvent
。通过这种方式,我得到了一个钩子,每次调整小部件的大小时,我都可以将代码注入其中。
为了让小部件真正更新其布局,我使用了QAbstractItemView::scheduleDelayedItemsLayout
(QAbstracTItemView::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