Thanks for your suggestion. I managed to find different solution so I am posting it in case anyone else is wondering how to do this. In the table view I connect to the actionTriggered signal of the scrollbars (please note, I use PyQt. The variable "self" is the same as "this" in C++):
self.verticalScrollBar().actionTriggered.connect(self.vertScrollActionTriggered)
self.horizontalScrollBar().actionTriggered.connect(self.horizScrollActionTriggered)
self.verticalScrollBar().actionTriggered.connect(self.vertScrollActionTriggered)
self.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
self.horizontalScrollBar().actionTriggered.connect(self.horizScrollActionTriggered)
self.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
To copy to clipboard, switch view to plain text mode
I will explain the scroll mode shortly. The action triggered methods:
def vertScrollActionTriggered(self, action):
vertBar=self.verticalScrollBar()
if action
==QtGui.
QAbstractSlider.
SliderSingleStepAdd: #if the user pressed the arrow if vertBar.value()==vertBar.maximum(): #if we are at the maximum
#set a new maximum to go one more step past the original maximum, this lets us "go past" the last row/column
vertBar.setMaximum(vertBar.maximum()+vertBar.singleStep())
vertBar.setValue(vertBar.maximum())
def vertScrollActionTriggered(self, action):
vertBar=self.verticalScrollBar()
if action==QtGui.QAbstractSlider.SliderSingleStepAdd: #if the user pressed the arrow
if vertBar.value()==vertBar.maximum(): #if we are at the maximum
#set a new maximum to go one more step past the original maximum, this lets us "go past" the last row/column
vertBar.setMaximum(vertBar.maximum()+vertBar.singleStep())
vertBar.setValue(vertBar.maximum())
To copy to clipboard, switch view to plain text mode
I look for only when a single step is being added as this is when a user presses the arrow of the scroll bar. If the scroll bar is at the maximum, then I add a single step to the maximum and increase the scroll bar to that new maximum. This makes it so that if the user wants to scroll past the last row, they can click the arrow to increase the range of the scroll bar and "go past" the last row. This is the same for horizontal.
You have to set the scroll mode to per pixel. Otherwise, if it is per item (which is default), when the user gets to the maximum point on the scroll bar, the table will "snap back" to the last row/column. This is because in the base QTableView code, in the scrollContentsBy method if the mode is per item, and the scroll bar value is the maximum value, it calls setOffsetToLastSection of the header instead of setting the offset to the value of the scroll bar, causing the "snapping" effect when the scroll bar gets to the maximum value, it can been seen in the following C++ code of the QTableView:
int oldOffset = d->horizontalHeader->offset();
if (horizontalScrollBar()->value() == horizontalScrollBar()->maximum()) <--------- this line!
d->horizontalHeader->setOffsetToLastSection();
else
d->horizontalHeader->setOffsetToSectionPosition(horizontalScrollBar()->value());
int newOffset = d->horizontalHeader->offset();
dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset;
} else {
d->horizontalHeader->setOffset(horizontalScrollBar()->value());
}
if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
int oldOffset = d->horizontalHeader->offset();
if (horizontalScrollBar()->value() == horizontalScrollBar()->maximum()) <--------- this line!
d->horizontalHeader->setOffsetToLastSection();
else
d->horizontalHeader->setOffsetToSectionPosition(horizontalScrollBar()->value());
int newOffset = d->horizontalHeader->offset();
dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset;
} else {
d->horizontalHeader->setOffset(horizontalScrollBar()->value());
}
To copy to clipboard, switch view to plain text mode
Hope this helps anyone else.
Bookmarks