How to get QTreeView cell width inside QItemDelegate sizeHint()?

3.5k views Asked by At

I have a custom QItemDelegate drawing text within a QTreeView. In paint(), I get the size of the cell from the style. I then draw the text, with wordwrap, using the current cell's width.

In sizeHint(), I really only want to calculate the height. The width should just be whatever the current cell width is. As the user changes the cell width, sizeHint would just calculate the new height of the word-wrapped text and return that.

The problem is that I can't get the cell width inside sizeHint() like I do in paint(). I was using :

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

This works in paint(), but returns -1 in sizeHint(). How do I get the current cell width in sizeHint()?

1

There are 1 answers

1
Serge VK On

Original: I use the base class' sizeHint() method to get the cell size as it would have been, then modify the QSize as needed, like this:

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;
}

Seems to work fine.

Edit: poster indicates that this doesn't work for him... So here's another option, maybe not the most elegant: add a view member to the delegate (which I can't think of a way to get from the delegate), and use the model index to get to the header's section size. For example:

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

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

protected:
    QAbstractItemView* theView;
};

and in the implementation

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;
}

Only thing left to do is in your code, after creating the delegate, call setView():

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