PyQt5:如何检测QSlider是否拖到最后

PyQt5: How to detect if QSlider is dragged to the end

我想检测用户是否将 QSlider 手柄一直拖到最后。

我创建了一个视频播放器,它在 QLabel 对象中显示视频帧。水平 QSlider 对象跟踪视频位置,也可以拖动以定位视频。我希望视频播放器在视频一直播放到最后时做一件事,而在用户将滑块一直拖到最后时做另一件事。

我尝试检测当滑块到达终点时鼠标按钮是否被按下,但无法在下面的脚本中运行。是否有其他方法可以确定当用户拖动滑块(按下鼠标按钮)时是否到达滑块的末端,而不是当视频自行播放到末端(未按下鼠标按钮)时?

from PyQt5 import QtCore, QtWidgets
import sys

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)

        self.label = QtWidgets.QLabel()
        self.label.setStyleSheet("border: 1px solid black")
        
        self.slider = QtWidgets.QSlider()
        self.slider.setOrientation(QtCore.Qt.Horizontal)

        lay = QtWidgets.QVBoxLayout(central_widget)
        #lay.addWidget(self.label)
        lay.addWidget(self.slider)

        self.resize(640, 480)
        
    def mousePressEvent(self, event):
        super().mousePressEvent(event)
        self.label.setText('Pressed')
        
    def mouseReleaseEvent(self, event):
        super().mouseReleaseEvent(event) 
        self.label.setText('Released')

    def sliderPressed(self, event):
        super().sliderPressed(event)
        self.label.setText('Pressed')
        
    def sliderReleased(self, event):
        super().sliderReleased(event)
        self.label.setText('Released')

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

QSliderclass继承QAbstractSlider, which has some signals and functions that make this relatively easy to achieve. In particular, the actionTriggered signal provides fine-grained slider movement notifications, which are independent of any programmatic value changes (i.e. via setValue). This allows tracking all mouse and keyboard changes (via dragging, wheel-scrolling, arrow/page keys, etc) before the value itself changes, which pretty much gives total control. There's also the sliderDown property,可用于识别拖动时鼠标按下的具体情况

下面是基于您的示例的简单演示:

from PyQt5 import QtCore, QtWidgets
import sys

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        self.label = QtWidgets.QLabel()
        self.label.setStyleSheet("border: 1px solid black")
        self.slider = QtWidgets.QSlider()
        self.slider.setOrientation(QtCore.Qt.Horizontal)
        self.slider.setRange(0, 10000)
        self.slider.setSingleStep(50)
        self.slider.setPageStep(500)
        self.slider.actionTriggered.connect(self.handleSliderAction)
        self.button = QtWidgets.QPushButton('Play')
        self.button.clicked.connect(self.handlePlay)
        lay = QtWidgets.QVBoxLayout(central_widget)
        lay.addWidget(self.label)
        lay.addWidget(self.slider)
        lay.addWidget(self.button)
        self.resize(640, 480)
        self.timer = QtCore.QTimer()
        self.timer.setInterval(10)
        self.timer.timeout.connect(
            lambda: self.slider.setValue(self.slider.value() + 1))

    def handleSliderAction(self, action):
        value = self.slider.sliderPosition()
        if value == self.slider.maximum():
            if self.slider.isSliderDown():
                self.label.setText('slider: end (down)')
            else:
                self.label.setText('slider: end')
        else:
            self.label.setText(f'slider: {value}')

    def handlePlay(self):
        if self.timer.isActive():
            self.timer.stop()
            self.button.setText('Play')
        else:
            self.button.setText('Pause')
            self.timer.start()

if __name__ == "__main__":

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())