简体   繁体   中英

How to apply QScrollerProperties to a QScroller, to get rid of overshoot?

As the title says I'm trying to make a scrollArea that uses QScroller with grabgesture so I can scroll by dragging on the widget. I found some good examples and got it working. Now I want to remove the overshoot that happens when you drag further than there is items in the widget.
But when I try to tweak the Qscroller, I can't seem to figure out how to apply the QScrollerProperties to the QScroller. Which is how I assume you remove the overshoot.
Here is an example of the code:

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QFormLayout,
    QGridLayout,
    QLabel,
    QScrollArea,
    QScroller,
    QScrollerProperties,
    QWidget,
)


class MainWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        scroll_area = QScrollArea()
        layout = QGridLayout(self)
        layout.addWidget(scroll_area)

        scroll_widget = QWidget()
        scroll_layout = QFormLayout(scroll_widget)

        for i in range(200):
            scroll_layout.addRow(QLabel('Label #{}'.format(i)))

        scroll_area.setWidget(scroll_widget)

        scroll = QScroller.scroller(scroll_area.viewport())
        scroll.grabGesture(scroll_area.viewport(), QScroller.LeftMouseButtonGesture)
        scroll.scrollerPropertiesChanged.connect(self.PropsChanged) #Just to see if I could registre a change

        props = scroll.scrollerProperties()
        props.setScrollMetric(QScrollerProperties.VerticalOvershootPolicy,QScrollerProperties.OvershootAlwaysOff)
        props.setScrollMetric(QScrollerProperties.DragStartDistance, 0.01)

        #Apply Qscroller properties here somehow?
        print(scroll.scrollerProperties().scrollMetric(QScrollerProperties.DragStartDistance))
        scroll.scrollerProperties = props #Maybe? Doesn't seem to change the overshoot?


    def PropsChanged(self):
        print("Something is being changed??")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

I'm not sure how to proceed from here. Any help would be appriciated :)

Just call scroll.setScrollerProperties(props) once you've set the new properties.

When you call scrollerProperties() you get "copy" of the current properties: it is not a pointer to the actual properties, so nothing changes unless you apply them back to the scroller.

It's almost like calling self.font() :

    font = self.font()
    font.setPointSize(20)
    # at this point, the widget font is still the same...
    # unless you do this:
    self.setFont(font)

The same applies to almost any property, like text() / setText() for labels, palette() / setPalette() , etc.

To prevent the vertical overshoot, you have to use setScrollMetric with VerticalOvershootPolicy , and set the value to OvershootAlwaysOff:

    props.setScrollMetric(QScrollerProperties.VerticalOvershootPolicy, 
        QScrollerProperties.OvershootAlwaysOff)
    scroll.setScrollerProperties(props)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM