PDA

View Full Version : Freeze any row within a QTableWidget/View



Baltharos
20th February 2015, 03:07
Sorry if this question has been asked a few times (with different variations), but I got this specific problem. I'm trying to create a custom table widget which can freeze a single row within the table. The frozen row then will act like a footer, but its position will change according to the scrollbar. If the scrollbar scroll beneath the row, the frozen row will stick to the top of the table. If the scrollbar scroll above the row, it will be at the bottom of the table.
The frozen column example makes do by overlaying a static model on top of the actual data model, but the overlay will be apparent for rows in the middle of the table. Is it possible to do this with a QTableWidget/QTableView (with a custom item model)?

ChrisW67
20th February 2015, 08:03
What you are asking for is entirely in the view and nothing to do with the model.

Why do you think the overlay will be apparent for rows in the middle of the table? It certainly is a more tricky exercise to keep the overlay in the correct place, but I do not see an obvious difference in approach.

Baltharos
3rd March 2015, 10:40
Sorry for replying too long.. I was looking for a method to customize the viewport within the QTableWidget itself. Now I use the same principle (QTableView within QTableWidget). By the example, the position of the overlay is connected to the resizeEvent and updateFrozenTableGeometry functions right? So all I need is to modify those functions?

ChrisW67
3rd March 2015, 20:22
You will have to capture scrolling events or check every time the base widget is painted to allow the overlay to track the vertical position of the row it is sitting above (or only show the overlay at top or bottom when the row of interest is not totally visible).
QTableView::rowViewportPosition()
QTableView::rowHeight()

Baltharos
4th March 2015, 04:09
So I need to connect the scrollbar to the geometry function?

ChrisW67
4th March 2015, 08:35
Maybe by overriding scrollContentsBy(), calling the parent class function and then looking at where the overlaid table should be positioned. The effective row position might change if you resize the widget also. Perhaps just reevaluating the overlay positioning inside a the parent widget's painteEvent() is possible. There are quite a few variables and it will take a bit of experimenting to find them all.

Baltharos
9th March 2015, 07:23
The scrolling now works! But how if I want to freeze a row that isn't in the viewport right now? Using rowViewportPosition, the function failed when I try a big row number.

ChrisW67
9th March 2015, 20:36
What do you mean "failed"?
Has the row in question been fetched from the model by the view? The view uses lazy fetching with canFetchMore() and fetchMore().

Baltharos
11th March 2015, 04:44
Found the problem (for now). The code can't take the tablewidget's verticalHeaderItem->text(). The horizontalHeaderItem works fine though. Why is it?