RDK RDK - 4 days ago 5
C++ Question

Qt: How to grow a QTablewidget when rendering in a delegate paint event?

I have quite the headache.

Let's consider the following:
I have a QListView with a custom delegate derived from QStyledItemDelegate.

In the delegate's

paint()
event I use a custom widget that I
render()
in the tableview. It's just a statick rendering and it's fine because I only need to show something without interacting.

My custom widget contains a QTableWidget imbedded in a vertical layout and some other labels that I fill with data in the
sizehint()
of the delegate. I then "force update" the layout of the custom widget with this technique: Qt: How to force a hidden widget to calculate its layout? - see
forceUpdate()
code.

Everything seems really fine, except one thing: the tablewidget of my custom widget seems to grow vertically when needed (when I add rows in it), BUT the rows are not rendered!!! Shrinking is ok though, setting a very big height for the custom widget somehow fixes the problem but it's not elegant and just reports the problem.

As it is just rendered and therefore not interactive, I don't want scrollbars but I need the QTableWidget to shrink/grow to show the added data. No more, no less.

The custom widget's GUI is made with the designer, everything is set to be dynamically growing and shrinking. Where's the catch? Has anyone seen such a behaviour? If yes, what is the magic parameters combination?


Some code for the eyes:


QSize ResultsRunDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {
// updating custom widget's data
item_widget->UpdateDisplay(index.row()+1);
forceUpdate(item_widget); //updating the layout
return item_widget->sizeHint(); }

void ResultsRunDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{

QPaintDevice* originalPaintDev = painter->device();
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());

painter->end();


forceUpdate(item_widget);
item_widget->render(painter->device(), QPoint(option.rect.x(), option.rect.y()), QRegion(0, 0, item_widget->rect().width()/*item_widget->sizeHint().width()*/, /*item_widget->rect().height()*/item_widget->sizeHint().height()), QWidget::DrawChildren);

painter->begin(originalPaintDev);
}


Any help would be greatly appreciated. Thx in advance!
I hope the question title is good, comments welcome.

Answer

the sizeHint() of a QTableView does not depend on its contents unfortunately. After the layout is calculated, you can get the ideal dimensions of the table from

int width = view->verticalHeader()->width() + view->horizontalHeader()->width() + view->frameWidth()*2;
int height= view->horizontalHeader()->height() + view->verticalHeader()->height() + view->frameWidth()*2;

and resize your widget accordingly.

Comments