PDA

View Full Version : QTableWidget remains at default size



CoderMan
2nd March 2012, 19:26
Once created, a QTableWidget gets some default size. I add rows to it and with the proper layouts, size policies and setStretchLastSection(true) the horizontal size is OK, filling all the available space and changing when the view gets resized. With many rows, the vertical size is also OK. But, with only a few rows, empty space remains at the bottom. How do I convince the QTableWidget to shrink vertically to the size of the data? Calling adjustSize() at various stages appears to do precisely nothing.

That is the only problem I originally had, and based on the answer I might be able to figure out a solution to my current problem:

I have several several custom widgets with a QTableWidget as a member variable, in a layout. Each table used to have its own scroll bars, but I decided I had to make the tables stay at a fixed height (matching the amount of data) and have the entire view scroll instead. This is proving... difficult. The view does scroll OK, but the tables inside it remain at the default size, in both directions now, no matter what I do. Well, I was able to enlarge them using setMinimumWidth(600), but a hardcoded size is not acceptable.

Seriously, I'm going nuts with all these nested layouts:
view layout, also has a layout for command buttons in addition to data layout
-> data layout, which is set to an empty QWidget, which is set to a QScrollArea, which is set to view layout
--> header layout for QLabel header and custom widget
---> table layout in the custom widget that finally contains the QTableWidget. Which seems to be depressed from being on the bottom of the layout stack and therefore not willing to expand to its full potential.

Please advice. Anybody willing to take a look at long-ish sample code?

The header layout, label and widget are all actually member variables in a struct that's supposed to represent a header+table combo, which isn't necessarily good design, but I tried removing it and that didn't help.

Spitfire
5th March 2012, 14:53
Hmmm I'm guessing that if you want a table to shrink to show only rows that are in it you'd have to sublass it, set vertical size policy to minimum and provide proper size hint depending on the content of the table.

If you can provide compilable example of your problem, or better yet - qt designer ui file demonstrating the problem I can look into it and maybe will come up with something usefull for you.

CoderMan
5th March 2012, 18:46
Thanks for the offer, but after some research, I have determined that the only solutions are indeed

resize() the widget at some point in time when calling that useless function actually has some effect (not in the constructor or showEvent)
subclass and reimplement sizeHint()
rely on stretchLastSection only.


Both 1) and 2) require you to somehow compute the correct value yourself. I went with option 2:


QSize SizedTable::minimumSizeHint() const
{
QSize size(QTableWidget::sizeHint());
int width = 0;
for (int a = 0; a < columnCount(); ++a)
{
width += columnWidth(a);
}
size.setWidth(width + (columnCount() * 1));
int height = horizontalHeader()->height();
for (int a = 0; a < rowCount(); ++a)
{
height += rowHeight(a);
}
size.setHeight(height + (rowCount() * 1));
return size;
}
QSize SizedTable::sizeHint() const
{
return minimumSizeHint();
}

Setting horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents) in the subclassed custom widget causes header style to be lost. Before rows (or columns) are deleted or added, QSizePolicy::Expanding must be
set, and after that is finished, QSizePolicy::Fixed must be set again. Not using size policies and just calling
table->setMinimumSize(table->sizeHint()) and table->setMaximumSize(table->sizeHint()) kills last section stretch.

I really thought that it would be easy to give these two orders to any Qt widget: "Resize yourself to the size of your own data, and then maintain that size". QTableWidget is not much of a "convenience" class in this regard.

Combined with the solution to my scrollarea problem (http://www.qtcentre.org/threads/47667-QScrollArea-in-a-QTabWidget-page?p=215233#post215233) I have finally managed to obtain a scrolling page that has several fixed-size tables whose size is not known until runtime, without extra whitespace around the tables. But, now the last section will not stretch! :mad: I'll try to fix that and will come back with either a solution or a plea for more help...

wysota
5th March 2012, 19:31
How do I convince the QTableWidget to shrink vertically to the size of the data?
You don't. If you really really really want it (if you do then think again a couple of times before you are sure you do) then subclass the view and recalculate the sizeHint() (don't forget about calling updateGeometry()) that will calculate how much space the items take and return the size you want.


Please advice.
My advice is that (based on your "I'm going nuts cause of nested layouts") you are probably doing something terribly wrong with your tables and you should rethink your approach.


Anybody willing to take a look at long-ish sample code?
No, not really. Anything longer than 50 lines goes to /dev/null :)

CoderMan
6th March 2012, 18:55
What's so bad about wanting to get rid of empty space around a table?

I'll try updateGeometry() when I return to this problem because for the time being I'm using tables. What other 2D grids are there? Grid layout with a QFrame in each cell for borders and on-click backgrounds? A tree maybe?

wysota
6th March 2012, 20:15
What's so bad about wanting to get rid of empty space around a table?
If you have a small fixed amount of data, maybe using a table view is not the best way of displaying it.

CoderMan
7th March 2012, 19:10
If you have a small fixed amount of data, maybe using a table view is not the best way of displaying it.

I wanted to use the same kind of widget for many data sets, some of which will be large. Some will start out small but grow from there.

Anyway, updateGeometry() accomplishes the same thing as switching size policies during item insertion.