PyQt5 - 实时 QSlider

Posted

技术标签:

【中文标题】PyQt5 - 实时 QSlider【英文标题】:PyQt5 - QSlider in real time 【发布时间】:2021-07-15 13:00:24 【问题描述】:

我正在创建一个软件来阅读和处理视频。我刚开始这个项目,但我已经遇到了问题。我想创建一个实时反应的滑块。目前,滑块仅移动几秒钟。 我的滑块就是这样设置的。

    self.slider = QSlider(Qt.Horizontal)
    self.slider.sliderMoved.connect(self.set_position)
    
    def set_position(self, position):
       self.mediaPlayer.setPosition(position)

我尝试使用 setTickPosition(QSlider::TickPosition position),但它并没有改变任何东西。可能我没有使用好功能。

也许这段代码可以帮助你看看我卡在哪里

from PyQt5.QtWidgets import QWidget, QApplication, QSlider, QHBoxLayout, QStyle, QFileDialog, QPushButton, QVBoxLayout
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.QtGui import QIcon
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtCore import Qt, QUrl
import sys

class Window(QWidget):
    def __init__(self):
        super().__init__()
        
        self.setWindowTitle("Slider tick settings")
        self.setGeometry(350, 100, 720, 700)
        self.setWindowIcon(QIcon("icon.png"))

        self.init_ui()
        
        self.show()
        
    def init_ui(self):
        
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        
        VideoWidget = QVideoWidget()
        
        self.slider = QSlider(Qt.Horizontal)
        self.slider.sliderMoved.connect(self.set_position)
        
        self.playBtn = QPushButton("Play")
        self.openFile = QPushButton("Open File")
        self.playBtn.clicked.connect(self.play_video)
        self.openFile.clicked.connect(self.open_file)
        
        self.qhbox = QHBoxLayout()
        self.qvbox = QVBoxLayout()
        
        self.qhbox.addWidget(self.slider)
        self.qhbox.addWidget(self.openFile)
        self.qhbox.addWidget(self.playBtn)
        self.qvbox.addLayout(self.qhbox) 
        self.qvbox.addWidget(VideoWidget)
        self.setLayout(self.qvbox)
    
        self.mediaPlayer.setVideoOutput(VideoWidget)
        
        self.mediaPlayer.stateChanged.connect(self.mediastate_changed)
        self.mediaPlayer.positionChanged.connect(self.position_changed)
        self.mediaPlayer.durationChanged.connect(self.duration_changed)
        
    def set_position(self, position):
        self.mediaPlayer.setPosition(position)
    
    def mediastate_changed(self, state):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
        else:
            self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
    
    def open_file(self):
        filename, _ = QFileDialog.getOpenFileName(self, "Open Video")
        if filename != '':
            self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(filename)))
            self.playBtn.setEnabled(True)
            #self.getRealFilename(filename)
            
    def position_changed(self, position):
        self.slider.setValue(position)
        
    def duration_changed(self, duration):
        self.slider.setRange(0, duration)
        
    def set_position(self, position):
        self.mediaPlayer.setPosition(position)
         
    def play_video(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState :
            self.mediaPlayer.pause()
        else :
            self.mediaPlayer.play()       
    
if __name__ == "__main__":
    app = QApplication(sys.argv)
    Window = Window()
    sys.exit(app.exec_())

【问题讨论】:

setTickPosition 设置刻度(滑块两侧的小线)的显示方式。也就是说,请提供minimal reproducible example 我用我的完整代码更新了我的帖子 我测试了它,它似乎工作得很好。请注意,由于某些视频格式的实现,它们不支持精确搜索,因此您可能只能访问“关键帧”,而不是您尝试搜索的确切点。不幸的是,对于当前的 QMediaPlayer 实现,没有解决方法。 好吧,我觉得我表达得很糟糕...我不想通过单击滑块来导航。我希望滑块以流畅的方式跟随视频的节奏,而不是每隔约 1 秒抖动一次 请注意,您定义了两次set_position 【参考方案1】:

刻度与滑块无关。

问题在于 QMediaPlayer 用于通知的默认间隔是 1000 毫秒。

如果您想更改它,请使用setNotifyInterval()适当 毫秒间隔(我建议不要使用小于 100-150 毫秒的值)。

【讨论】:

以上是关于PyQt5 - 实时 QSlider的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 - 实时 QSlider

PyQt5 从主模块外部实时登录 QTextedit

动态指针时钟:利用pyqt5制作指针钟表显示实时时间

如何实时更新 PyQt5 标签?

如何使用串行向我的 PyQt5 窗口添加实时(更新)图?

尝试使用 PyQt5 获得 GUI 的实时图