如何在QItemDelegate的sizeHint()中获取QTreeView单元格宽度?

5 投票
1 回答
3497 浏览
提问于 2025-04-17 10:39

我有一个自定义的 QItemDelegate,用来在 QTreeView 中绘制文本。在 paint() 方法里,我从样式中获取单元格的大小。然后,我根据当前单元格的宽度来绘制文本,并且支持自动换行。

在 sizeHint() 方法中,我其实只想计算高度。宽度应该就是当前单元格的宽度。用户改变单元格宽度时,sizeHint 只需要计算换行文本的新高度并返回就可以了。

问题是,我在 sizeHint() 中无法像在 paint() 中那样获取单元格的宽度。我之前使用的是:

style = QApplication.style()
style.subElementRect(QStyle.SE_ItemViewItemText, option).width()

这个在 paint() 中可以正常工作,但在 sizeHint() 中却返回 -1。我该如何在 sizeHint() 中获取当前单元格的宽度呢?

1 个回答

6

原文: 我使用基类的 sizeHint() 方法来获取单元格的大小,然后根据需要修改 QSize,像这样:

QSize MyDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
    QSize sz=QItemDelegate::sizeHint(option, index);
    int h=sz.height();

    < MODIFY h HERE > 

    sz.setHeight(h);
    return sz;
}

看起来效果不错。

编辑: 发帖者表示这对他不起作用……所以这里有另一个选择,可能不是最优雅的:在委托中添加一个视图成员(我想不出从委托中获取的方法),然后使用模型索引来获取表头的部分大小。例如:

class MyDelegate : public QItemDelegate
{
public:
    <the usual, then add>

    void setView(QAbstractItemView* v) { theView=v; }

protected:
    QAbstractItemView* theView;
};

在实现中

QSize MyDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
    int theWidth=-1;

    // handle other types of view here if needed
    QTreeView* tree=qobject_cast<QTreeView*>(theView);
    if(tree)
    {
        qDebug("WIDTH @ %d : %d",index.column(),tree->header()->sectionSize(index.column()));
        theWidth=tree->header()->sectionSize(index.column());
    }

    QSize sz=QItemDelegate::sizeHint(option, index);
    if(theWidth>=0)
        sz.setWidth(theWidth);

    // compute height here and call sz.setHeight()

    return sz;
}

剩下的就是在你的代码中,创建委托后调用 setView():

MyDelegate* theDelegate=new MyDelegate(...);
theDelegate->setView(theView);

撰写回答