4

I have a bunch of data in a QTableWidget and I would like to be able to scroll to a particular column. I'm currently using scrollToItem(self.item(0, col)). However, this hardcodes the row to 0. It causes problems if a user is looking at row 100 and scrolls to a specific column since it loses their vertical place in the table.

Is there a way to find what row the user is currently viewing inside of the QScrollArea that the QTableWidget provides? If so, I could easily replace that defaulted row with the correct one.

Maybe there is another way to achieve this result with something like .ensureWidgetVisible()? However, I'm not sure how to get the correct widget that I would want to scroll to or make visible.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
durden2.0
  • 9,222
  • 9
  • 44
  • 57
  • I can seem to get it going by getting the value of the vertical scroll bar before calling scrollToItem and then setting the scroll bar value back to this after callingscrollToItem: `curr_pos = self.verticalScrollBar().value() self.scrollToItem(self.item(0, col)) self.verticalScrollBar().setValue(curr_pos)` – durden2.0 Feb 10 '12 at 22:20

1 Answers1

3

One way to do this is to get the row-index of the first visible row, and then use that to find the first visible item in the column you want to scoll to:

def scrollToColumn(self, column=0):
    visible = self.itemAt(0, 0)
    if visible is not None:
        self.scrollToItem(self.item(visible.row(), column))

Since the row of the item you're scrolling to is already visible, the view should not scroll itself vertically (unless the verticalScrollMode is ScrollPerPixel and the item at point (0, 0) is not fully visible).

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • So itemAt(0, 0) returns the cell currently in the visible rectangle? In other words, the current top left corner, not the absolute top left corner? – durden2.0 Feb 13 '12 at 14:32
  • Nevermind, a simple test verified that for me. Yes, itemAt(..) does in fact return the current item in the top left corner. Thus, the coordinates to itemAt are relative to the current viewable area, not the absolute coordinates of the entire scroll area. – durden2.0 Feb 13 '12 at 14:34
  • Is there any reason to choose this solution over the one that captures the current scroll bar value and resets it? Are there any pitfalls with either that I'm not taking into account? – durden2.0 Feb 13 '12 at 14:35
  • @durden2.0. I would say my solution is more efficient, because the view is only scrolled once. However, the difference is probably small, and is unlikely to be noticeable to the user. – ekhumoro Feb 13 '12 at 19:03
  • That's a good point. I tested both solutions successfully. However, I do think that your solution is probably a little cleaner since there might be the potential in my original solution to cause 'jerky' scrollbar behavior where it scrolls after scrollToItem and then is forced back. I didn't see this behavior in my code, but seems like a possibility. I prefer your solution. – durden2.0 Feb 13 '12 at 20:09