QTreeView:resizeRowsToContents等效或如何在行中自动换行文本

时间:2016-07-25 21:22:57

标签: qt qt5 qtreeview

我有一个QTreeView,其中包含多个列(如表格)。树中的列具有固定大小。我需要调整行高,并使用像QTableView::resizeRowsToContents这样的多行文本。 我怎么能这样做?

我尝试使用重新实现QStyledItemDelegate的自定义sizeHint,但我不知道如何计算已知宽度的多行文字块高度。

1 个答案:

答案 0 :(得分:1)

使用QStyledItemDelegate是正确的方法。在sizeHint函数中,您可以将样式选项textQFontMetrics类一起使用:

QSize MyItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override {
    QSize baseSize = this->QStyledItemDelegate::sizeHint(option, index);
    baseSize.setHeight(10000);//something very high, or the maximum height of your text block

    QFontMetrics metrics(option.font);
    QRect outRect = metrics.boundingRect(QRect(QPoint(0, 0), baseSize), Qt::AlignLeft, option.text);
    baseSize.setHeight(outRect.height());
    return baseSize;
}

注意:现在我无法对此进行测试,但它应该可以正常运行。如果输出不符合您的需要,您可能需要调整metrics.boundingRect的调用

修改
看起来sizeHint只会被调用一次来创建初始布局,但是在调整列大小之后不会。

最终的想法可能是覆盖QAbstractItemModel::data函数以使用Qt::SizeHintRole返回所需的大小。您可以将其添加到现有模型中,也可以提供代理模型来执行此操作:

QSize MyModel::data(const QModelIndex &index, int role) const override {
    switch(role) {
        //...
    case Qt::SizeHintRole:
    {
        QSize baseSize(getFixedWidth(index.column()), baseSize.setHeight(10000));//something very high, or the maximum height of your text block

        QFontMetrics metrics(this->data(index, Qt::FontRole).value<QFont>());
        QRect outRect = metrics.boundingRect(QRect(QPoint(0, 0), baseSize), Qt::AlignLeft, this->data(index, Qt::DisplayRole)));
        baseSize.setHeight(outRect.height());
        return baseSize;
    }
        //...
    }
}

重要提示:每次调整视图大小时,您都必须为所有这些项发出dataChanged信号。 getFixedWidth是您必须实现的,以返回给定列的当前宽度。