Scrolling QTableWidget smoothly BY MOUSE WHEEL

Viewed 852

I tried .setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel) which works nicely but requires user to move mouse to the scroll bar and use it to experience the smooth scroll but the mouse wheel works the old way with jumpy scrolling, i wonder if there a way to make the scrolling behave the same when using the mouse wheel ?

1 Answers

You should use self.widget.verticalScrollBar().setSingleStep(step).

QTableWidget inherits QTableView, which inherits QAbstractItemView, which inherits QAbstractScrollArea, which has method verticalScrollBar(), which brings us to the QScrollBar Class that inherits QAbstractSlider, which finally has setSingleStep(step) method (maybe there is shorter path?).

Here's the complete code:

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class Window(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.setWindowTitle("Scrolling QTableWidget smoothly BY MOUSE WHEEL")
        
        label = QLabel("singleStep:")
        self.spinbox = QSpinBox()
        self.spinbox.setValue(1)
        self.spinbox.setMinimum(1)
        self.spinbox.setMaximum(200)
        self.spinbox.valueChanged.connect(self.on_value_changed)

        self.widget = QTableWidget(100, 5)

        for i in range(100):
            for j in range(5):
                self.widget.setItem(i, j, QTableWidgetItem(str(i+j)))

        self.widget.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        #self.widget.verticalScrollBar().setSingleStep(1)
        self.set_single_step()

        spinbox_layout = QHBoxLayout()
        spinbox_layout.addStretch()
        spinbox_layout.addWidget(label)
        spinbox_layout.addWidget(self.spinbox)

        layout = QVBoxLayout()
        layout.addLayout(spinbox_layout)
        layout.addWidget(self.widget)
        self.setLayout(layout)

    def on_value_changed(self, step):
        self.set_single_step()

    def set_single_step(self):
        self.widget.verticalScrollBar().setSingleStep(self.spinbox.value())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.resize(800, 600)
    window.show()
    sys.exit(app.exec())

You can increase/decrease step in spinbox to see how it behaves. I hope that is what you asked for.

Related