当前位置: 首页 > 面试题库 >

我如何使用pafy制作进度条的线程

韩季
2023-03-14
问题内容

我正在尝试解决程序中的问题,而这个问题是当我开始下载视频时程序没有响应,我也看不到进度栏移动,因此我尝试使用线程模块,但无法解决问题,因此我可以解决问题

通过此代码,我可以下载视频并将数据发送到另一个函数,以检索用于将其连接到进度条的信息

def video(self):
    video_url = self.lineEdit_4.text()
    video_save = self.lineEdit_3.text()

    pafy_video = pafy.new(video_url)
    type_video = pafy_video.videostreams

    quality = self.comboBox.currentIndex()

    start_download = type_video[quality].download(filepath=video_save,callback=self.video_progressbar)

该代码是从视频功能接收到的信息,用于与进度条连接

def video_progressbar(self,total, recvd, ratio, rate, eta):
    self.progressBar_2.setValue(ratio * 100)

我使用; python3.5 pyqt5 pafy


问题答案:

转移到另一个线程的一种方法是创建一个QObject驻留在另一个线程中的线程,并在插槽中执行该任务。并且该插槽必须通过QMetaObject::invokeMethod或信号来调用。

with QThread and QMetaObject::invokeMethod:

import pafy
from PyQt5 import QtCore, QtWidgets

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

        self.le_url = QtWidgets.QLineEdit("https://www.youtube.com/watch?v=bMt47wvK6u0")
        path = QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.DownloadLocation)
        self.le_output = QtWidgets.QLineEdit(path)
        self.btn_quality = QtWidgets.QPushButton("Get qualities")
        self.combo_quality = QtWidgets.QComboBox()
        self.btn_download = QtWidgets.QPushButton("Download")
        self.progressbar = QtWidgets.QProgressBar(maximum=100)

        self.downloader = DownLoader()
        thread = QtCore.QThread(self)
        thread.start()
        self.downloader.moveToThread(thread)

        self.btn_quality.clicked.connect(self.on_clicked_quality)
        self.btn_download.clicked.connect(self.download)
        self.btn_download.setDisabled(True)
        self.downloader.progressChanged.connect(self.progressbar.setValue)
        self.downloader.qualitiesChanged.connect(self.update_qualityes)
        self.downloader.finished.connect(self.on_finished)

        form_lay = QtWidgets.QFormLayout(central_widget)
        form_lay.addRow("Url: ", self.le_url)
        form_lay.addRow(self.btn_quality)
        form_lay.addRow("qualities: ", self.combo_quality)
        form_lay.addRow("Output: ", self.le_output) 
        form_lay.addRow(self.btn_download)  
        form_lay.addRow(self.progressbar)

    @QtCore.pyqtSlot()
    def on_finished(self):
        self.update_disables(False)

    @QtCore.pyqtSlot()
    def on_clicked_quality(self):
        video_url = self.le_url.text()
        QtCore.QMetaObject.invokeMethod(self.downloader, "get_qualities",
            QtCore.Qt.QueuedConnection,
            QtCore.Q_ARG(str, video_url))

    @QtCore.pyqtSlot(list)
    def update_qualityes(self, types_of_video):
        for t in types_of_video:
            self.combo_quality.addItem(str(t), t)
        self.btn_download.setDisabled(False)

    @QtCore.pyqtSlot()
    def download(self):
        video_save = self.le_output.text()
        d = self.combo_quality.currentData()
        QtCore.QMetaObject.invokeMethod(self.downloader, "start_download",
            QtCore.Qt.QueuedConnection,
            QtCore.Q_ARG(object, d),
            QtCore.Q_ARG(str, video_save))
        self.update_disables(True)

    def update_disables(self, state):
        self.combo_quality.setDisabled(state)
        self.btn_quality.setDisabled(state)
        self.le_output.setDisabled(state)
        self.le_url.setDisabled(state)
        self.btn_download.setDisabled(not state)

class DownLoader(QtCore.QObject):
    progressChanged = QtCore.pyqtSignal(int)
    qualitiesChanged = QtCore.pyqtSignal(list)
    finished = QtCore.pyqtSignal()

    @QtCore.pyqtSlot(str)
    def get_qualities(self, video_url):
        pafy_video = pafy.new(video_url)
        types_of_video = pafy_video.allstreams # videostreams
        self.qualitiesChanged.emit(types_of_video)

    @QtCore.pyqtSlot(object, str)
    def start_download(self, d, filepath):
        d.download(filepath=filepath, callback=self.callback)

    def callback(self, total, recvd, ratio, rate, eta):
        val = int(ratio * 100)
        self.progressChanged.emit(val)
        if val == 100:
            self.finished.emit()

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.resize(320, 480)
    w.show()
    sys.exit(app.exec_())

with threading.Thread

import pafy
import threading
from PyQt5 import QtCore, QtWidgets

class MainWindow(QtWidgets.QMainWindow):
    qualitiesChanged = QtCore.pyqtSignal(list)
    progressChanged = QtCore.pyqtSignal(int)
    finished = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)

        self.le_url = QtWidgets.QLineEdit("https://www.youtube.com/watch?v=bMt47wvK6u0")
        path = QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.DownloadLocation)
        self.le_output = QtWidgets.QLineEdit(path)
        self.btn_quality = QtWidgets.QPushButton("Get qualities")
        self.combo_quality = QtWidgets.QComboBox()
        self.btn_download = QtWidgets.QPushButton("Download")
        self.progressbar = QtWidgets.QProgressBar(maximum=100)

        self.btn_quality.clicked.connect(self.on_clicked_quality)
        self.btn_download.clicked.connect(self.download)
        self.btn_download.setDisabled(True)
        self.progressChanged.connect(self.progressbar.setValue)
        self.qualitiesChanged.connect(self.update_qualityes)
        self.finished.connect(self.on_finished)

        form_lay = QtWidgets.QFormLayout(central_widget)
        form_lay.addRow("Url: ", self.le_url)
        form_lay.addRow(self.btn_quality)
        form_lay.addRow("qualities: ", self.combo_quality)
        form_lay.addRow("Output: ", self.le_output) 
        form_lay.addRow(self.btn_download)  
        form_lay.addRow(self.progressbar)

    @QtCore.pyqtSlot()
    def on_finished(self):
        self.update_disables(False)

    @QtCore.pyqtSlot()
    def on_clicked_quality(self):
        video_url = self.le_url.text()
        threading.Thread(target=self.get_qualities, args=(video_url,)).start()

    def get_qualities(self, video_url):
        pafy_video = pafy.new(video_url)
        types_of_video = pafy_video.allstreams # videostreams
        self.qualitiesChanged.emit(types_of_video)

    @QtCore.pyqtSlot(list)
    def update_qualityes(self, types_of_video):
        for t in types_of_video:
            self.combo_quality.addItem(str(t), t)
        self.btn_download.setDisabled(False)

    @QtCore.pyqtSlot()
    def download(self):
        video_save = self.le_output.text()
        d = self.combo_quality.currentData()
        threading.Thread(target=d.download, kwargs={'filepath': video_save, 'callback': self.callback}, daemon=True).start()

    def callback(self, total, recvd, ratio, rate, eta):
        print(ratio)
        val = int(ratio * 100)
        self.progressChanged.emit(val)
        if val == 100:
            self.finished.emit()

    def update_disables(self, state):
        self.combo_quality.setDisabled(state)
        self.btn_quality.setDisabled(state)
        self.le_output.setDisabled(state)
        self.le_url.setDisabled(state)
        self.btn_download.setDisabled(not state)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.resize(320, 480)
    w.show()
    sys.exit(app.exec_())


 类似资料:
  • 问题内容: 如何在html / css /javascript中制作进度条。我真的不想使用Flash。在这里可以找到类似的东西 我真正想要的只是一个“进度条”,它可以更改我在PHP中提供的值。您会如何处理?有什么好的教程吗? 问题答案: 您可以通过css控制div的宽度来实现。大致遵循以下原则: 如果您愿意,可以从php发送该宽度值。

  • 本文向大家介绍如何使用纯html制作一个进度条?相关面试题,主要包含被问及如何使用纯html制作一个进度条?时的应答技巧和注意事项,需要的朋友参考一下 HTML中的progress () 元素用来显示一项任务的完成进度.虽然规范中没有规定该元素具体如何显示,浏览器开发商可以自己决定,但通常情况下,该元素都显示为一个进度条形式. 所有不建议在生产业务中使用 MDN链接

  • 问题内容: 我的主类从文件加载配置,然后显示一个框架。我想制作一个带有进度条(如Eclipse)的启动画面,以便在加载文件时进度会增加,并且在加载文件后启动画面会消失。然后我的主机被加载。 MainClass代码: 我在Swing方面没有太多经验,所以请提出建议。 更新: 我发现了以下示例,但没有什么问题: 当计数器达到指定的数字时,它应停止在(300)位置,直到不停止计时器并隐藏启动画面而永远计

  • 我想展示在外部库中执行的计算的进度。 例如,如果我有一些计算方法,我想在我的Form类中为100000个值使用它,我可以写: 我应该在每次计算后执行步骤。但是如果我在外部方法中执行所有100000次计算呢?如果我不想让这个方法依赖于进度条,我应该什么时候“执行步骤”?例如,我可以写 但我不想那样做。

  • 问题内容: 当Google提供许多指向Stackoverflow的准确结果时,过去很容易找到我的问题的解决方案。但是,我没有找到解决这个问题的方法。如果您有任何建议我应该去哪里解决这个问题,请给我链接到答案。 情况是我想从数据库中搜索索引。该 索引过程 被触发。它需要几分钟才能完成,所以 我想在进度栏中显示该索引编制过程 。我知道如何使用客户端和PHP作为服务器端发出通用的ajax请求,但是我很难

  • 本文向大家介绍请使用纯HTML制作一个进度条相关面试题,主要包含被问及请使用纯HTML制作一个进度条时的应答技巧和注意事项,需要的朋友参考一下 progress是HTML5的一个新元素,表示定义一个进度条,用途很广泛,可以用在文件上传的进度显示,文件下载的进度显示,也可以作为一种loading的加载状态条使用。 max属性表示进度条的进度最大值,如果有此值,必须是大于0的有效浮点数。max的默认值