如何检测滚动条在 QPlainTextEdit 中向下移动

how to detect scroll bar move down in QPlainTextEdit

我正在为 QPlainTextEdit 中滚动条向下滚动的信号编写槽方法。

我只找到这个信号QPlainTextEdit.verticalScrollBar().valueChanged

我测试了这个信号,它在滚动到新位置时返回了位置编号。

我的目的是当滚动条向下移动时触发slot方法。但是在那个信号中,当向上移动时它也会触发插槽。 我阅读了文档,但找不到其他信号。

一种可能的解决方案是保存之前的位置并使用 sliderPosition 属性:

与新位置进行比较
from PyQt5.QtWidgets import QApplication, QPlainTextEdit


class PlainTextEdit(QPlainTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.last_position = self.verticalScrollBar().sliderPosition()
        self.verticalScrollBar().sliderMoved.connect(self.handle_value_changed)

    def handle_value_changed(self, position):
        if position > self.last_position:
            print("down")
        else:
            print("up")
        self.last_position = position


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    w = PlainTextEdit()
    w.show()

    sys.exit(app.exec_())

另一种可能的选择是实现对 QScrollBar 的 mousePressEvent 和 mouseMoveEvent 事件的使用:

from PyQt5.QtCore import QPoint, Qt
from PyQt5.QtWidgets import QApplication, QPlainTextEdit, QScrollBar


class ScrollBar(QScrollBar):
    last_pos = QPoint()

    def mousePressEvent(self, event):
        self.last_pos = event.pos()
        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)
        if event.pos().y() > self.last_pos.y():
            print("down")
        else:
            print("up")
        self.last_pos = event.pos()


class PlainTextEdit(QPlainTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.vertical_scrollbar = ScrollBar(Qt.Vertical)
        self.setVerticalScrollBar(self.vertical_scrollbar)


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    w = PlainTextEdit()
    w.show()

    sys.exit(app.exec_())

或:

from PyQt5.QtCore import QEvent, QPoint
from PyQt5.QtWidgets import QApplication, QPlainTextEdit


class PlainTextEdit(QPlainTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.last_pos = QPoint()
        self.verticalScrollBar().installEventFilter(self)

    def eventFilter(self, obj, event):
        if obj is self.verticalScrollBar():
            if event.type() == QEvent.MouseButtonPress:
                self.last_pos = event.pos()
            elif event.type() == QEvent.MouseMove:
                if event.pos().y() > self.last_pos.y():
                    print("down")
                else:
                    print("up")
                self.last_pos = event.pos()
        return super().eventFilter(obj, event)


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    w = PlainTextEdit()
    w.show()

    sys.exit(app.exec_())