Search code examples
pythonpyqt5pyqt6

Detect scroll occurrence in PyQt


I wrote this scroll area in pyqt5

from PyQt5.QtWidgets import (QWidget, QSlider, QLineEdit, QLabel, QPushButton, QScrollArea,QApplication,
                             QHBoxLayout, QVBoxLayout, QMainWindow)
from PyQt5.QtCore import Qt, QSize
from PyQt5 import QtWidgets, uic
import sys


class MainWindow(QMainWindow):

def __init__(self):
    super().__init__()
    self.initUI()

def initUI(self):
    self.scroll = QScrollArea()          
    self.widget = QWidget()            
    self.vbox = QVBoxLayout()       

    for i in range(1,50):
        object = QLabel("TextLabel")
        self.vbox.addWidget(object)

    self.widget.setLayout(self.vbox)

    #Scroll Area Properties
    self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
    self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
    self.scroll.setWidgetResizable(True)
    self.scroll.setWidget(self.widget)

    self.setCentralWidget(self.scroll)

    self.setGeometry(600, 100, 1000, 900)
    self.setWindowTitle('Scroll Area Demonstration')
    self.show()

    return

def main():
    app = QtWidgets.QApplication(sys.argv)
    main = MainWindow()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

What I want is:

1.When you scroll up -> print('scroll up occurred ') 2.When you scroll down -> print('scroll down occurred ') 3.When the scroll reaches the end of the scroll area -> print('The scroll has reached the end') 4.When scroll down handle is clicked -> print('down handle is triggered') 5.When scroll up handle is clicked -> print('up handle is triggered')


Solution

  • This should work for your problem:

    from PyQt5.QtWidgets import (QWidget, QSlider, QLineEdit, QLabel, QPushButton, QScrollArea, QApplication,
                                 QHBoxLayout, QVBoxLayout, QMainWindow)
    from PyQt5.QtCore import Qt, QSize
    from PyQt5 import QtWidgets, uic
    import sys
    
    
    class MainWindow(QMainWindow):
    
        def __init__(self):
            super().__init__()
            self.initUI()
    
        def initUI(self):
            self.scroll = QScrollArea()
            self.widget = QWidget()
            self.vbox = QVBoxLayout()
    
            for i in range(1, 50):
                object = QLabel("TextLabel")
                self.vbox.addWidget(object)
    
            self.widget.setLayout(self.vbox)
    
            # Scroll Area Properties
            self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
            self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.scroll.setWidgetResizable(True)
            self.scroll.setWidget(self.widget)
    
            self.setCentralWidget(self.scroll)
    
            self.setGeometry(600, 100, 1000, 900)
            self.setWindowTitle('Scroll Area Demonstration')
            self.show()
    
            # Connect signals to slots
            self.position = self.scroll.verticalScrollBar().sliderPosition()
            self.scroll.verticalScrollBar().actionTriggered.connect(self.on_scroll)
            self.scroll.verticalScrollBar().valueChanged.connect(self.scrolled)
            return
    
        def on_scroll(self, action):
            
            # In case you scroll using the mouse wheel or clicking the bar.
            if(self.scroll.verticalScrollBar().sliderPosition() > self.position):
                print('scroll down occurred ')
                self.position = self.scroll.verticalScrollBar().sliderPosition()
            if(self.scroll.verticalScrollBar().sliderPosition() < self.position):
                print('scroll up occurred ')
                self.position = self.scroll.verticalScrollBar().sliderPosition()
            
            # SliderSingleStepAdd for when you click the arrow up.
            # SliderPageStepAdd for when you click the bar up.    
            if (action == QtWidgets.QAbstractSlider.SliderSingleStepAdd) or (action == QtWidgets.QAbstractSlider.SliderPageStepAdd):
                print('scroll down occurred ')
            # SliderSingleStepSub for when you click the arrow down.
            # SliderPageStepSub for when you click the bar down.
            if (action == QtWidgets.QAbstractSlider.SliderSingleStepSub) or (action == QtWidgets.QAbstractSlider.SliderPageStepSub):
                print('scroll up occurred ')
    
        # https://stackoverflow.com/questions/23525448/python-pyqt-scrollbar-in-the-end-position-event
        def scrolled(self, value):
            if value == self.scroll.verticalScrollBar().maximum():
                print ('reached max') # that will be the bottom/right end
            if value == self.scroll.verticalScrollBar().minimum():
                print ('reached min') # top/left end
    
    def main():
        app = QtWidgets.QApplication(sys.argv)
        main = MainWindow()
        sys.exit(app.exec_())
    
    
    if __name__ == '__main__':
        main()