1
votes

I have a slightly customized QTableView showing a model that I've developed. When I instruct the TableView to resizeColumnToContents, I end up with an extra buffer of about 20 pixels on either side of the column's text. This is major overkill for my table, as you can see below.

Screenshot showing the unnecessary buffer

The user can manually resize the column to remove that buffer, but it's annoying when there are a lot of columns.

How might I change this buffer/margin size programmatically? I'm willing to use delegates, sizeHints, styleSheets, whatever it takes. I just can't find where this value is set.

Edit: Stepping through QHeaderView::sizeHint() and QHeaderView::sectionSizeFromContents() showed me that this is happening because I have sorting enabled (line 2588 of qheaderview.cpp). Disabling sorting removed the horizontal buffer.

Why on earth would the sizehint add a buffer of the header's height to its width if sorting is enabled? The sort indicator appears above the header (see below). The sort indicator has no relevance to the required column width. Weird.

enter image description here

I can't see a way around this other than implementing my own QHeaderView class. Is there a better way?

1
What QStyle is your app using? All of the styles I've seen have the sort-arrow displayed at the right side of the column-header rectangle, which is why the sizehint is adding space for it there. - Jeremy Friesner
Good question. I'm running on Windows 7 x64, so I think it's defaulting to the Vista style. - Phlucious

1 Answers

0
votes

It's a bug in Qt4 that got fixed in Qt5. It's leaving extra space for a sort indicator that's not there when using the Vista style.

Implementing my own QHeaderView subclass was the only way to fix this in qt 4.8.

QSize MyHeaderView::sectionSizeFromContents(int logicalIndex) const
{
    QSize sz = QHeaderView::sectionSizeFromContents(logicalIndex);

    //Qt 4.8.x workaround to remove horizontal spacing from sort indicator with vista style
    if(isSortIndicatorShown())
    {
        auto style = qApp->style();
        if(orientation() == Qt::Horizontal && style->objectName() == "windowsvista")
        {
            int margin = style->pixelMetric(QStyle::PM_HeaderMargin, 0, this);
            sz.rwidth() -= margin + sz.height();
        }
    }

    return sz;
}

I tested this on Windows 7 and 10 using Qt 5.11.1 and the workaround is no longer necessary. I'm not sure when, exactly, it was fixed.