1. <small id='YJeMr'></small><noframes id='YJeMr'>

  2. <tfoot id='YJeMr'></tfoot>
      <bdo id='YJeMr'></bdo><ul id='YJeMr'></ul>

    <i id='YJeMr'><tr id='YJeMr'><dt id='YJeMr'><q id='YJeMr'><span id='YJeMr'><b id='YJeMr'><form id='YJeMr'><ins id='YJeMr'></ins><ul id='YJeMr'></ul><sub id='YJeMr'></sub></form><legend id='YJeMr'></legend><bdo id='YJeMr'><pre id='YJeMr'><center id='YJeMr'></center></pre></bdo></b><th id='YJeMr'></th></span></q></dt></tr></i><div id='YJeMr'><tfoot id='YJeMr'></tfoot><dl id='YJeMr'><fieldset id='YJeMr'></fieldset></dl></div>
      <legend id='YJeMr'><style id='YJeMr'><dir id='YJeMr'><q id='YJeMr'></q></dir></style></legend>

      GUI在下载PyQt5和Pytube时冻结

      时间:2024-08-11

        <legend id='PMbf8'><style id='PMbf8'><dir id='PMbf8'><q id='PMbf8'></q></dir></style></legend>

            <i id='PMbf8'><tr id='PMbf8'><dt id='PMbf8'><q id='PMbf8'><span id='PMbf8'><b id='PMbf8'><form id='PMbf8'><ins id='PMbf8'></ins><ul id='PMbf8'></ul><sub id='PMbf8'></sub></form><legend id='PMbf8'></legend><bdo id='PMbf8'><pre id='PMbf8'><center id='PMbf8'></center></pre></bdo></b><th id='PMbf8'></th></span></q></dt></tr></i><div id='PMbf8'><tfoot id='PMbf8'></tfoot><dl id='PMbf8'><fieldset id='PMbf8'></fieldset></dl></div>

                <bdo id='PMbf8'></bdo><ul id='PMbf8'></ul>
              • <tfoot id='PMbf8'></tfoot>
              • <small id='PMbf8'></small><noframes id='PMbf8'>

                  <tbody id='PMbf8'></tbody>
                本文介绍了GUI在下载PyQt5和Pytube时冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                我已经用Python制作了一个桌面应用程序,并使用了可以从YouTube下载视频的PyQt5和Pytube。当下载正在进行时,我想向用户显示动画。实际上我是这样做的,但是当文件正在下载时,PyQt窗口似乎冻结了,一切都会暂停,直到下载完成。有人知道为什么会发生这种事吗?我如何修复它?

                以下是代码片段:

                def download_created(self, qual): # Used in 'selection' method
                    selected_stream = yt.streams.get_by_resolution(qual)
                    self.progress_func()
                    try:
                        self.download_btn.setCurrentIndex(-1)
                        selected_stream.download(self.askLocation() + "/")
                    except:
                        pass
                    
                # This gets the quality that the user chooses
                def selection(self):
                    global quality
                    quality = self.download_btn.currentText()
                    try:
                        self.download_created(quality) # Calls a method called 'download'
                    except:
                        self.start_anime()
                # Fetching the details about the Link from Youtube
                def download_youtube(self):
                    global check
                    if check != self.get_input():
                        check = self.get_input()
                        self.download_btn.clear()
                        enter_url = self.get_input()
                        try:
                            global yt
                            yt = pytube.YouTube(
                                enter_url,
                                on_progress_callback = on_progress, 
                                on_complete_callback = self.complete_func)
                            
                            self.start_anime()
                        except:
                            self.input_error()
                        VIDEO_TITLE = (yt.title)
                        global VIDEO_ID
                        VIDEO_ID = (yt.video_id)
                        videos = yt.streams.filter(mime_type="video/mp4", progressive="True")
                
                        # Display all the available qualities
                        for i in videos:
                            self.download_btn.addItem(i.resolution)
                        self.download_btn.currentIndexChanged.connect(self.selection)
                

                推荐答案

                您必须在另一个线程中执行耗时的任务,例如,在您的情况下,执行获取流和下载的任务。

                import sys
                import threading
                from functools import cached_property
                
                from PyQt5 import QtCore, QtWidgets
                
                import pytube
                
                
                class QPyTube(QtCore.QObject):
                    initialized = QtCore.pyqtSignal(bool, str)
                    download_started = QtCore.pyqtSignal()
                    download_progress_changed = QtCore.pyqtSignal(int)
                    download_finished = QtCore.pyqtSignal()
                
                    def __init__(self, url):
                        super().__init__()
                        self._url = url
                        self._yt = None
                        self._mutex = threading.Lock()
                
                        threading.Thread(target=self._init, daemon=True).start()
                
                    @property
                    def url(self):
                        return self._url
                
                    @cached_property
                    def resolutions(self):
                        return list()
                
                    def _init(self):
                        with self._mutex:
                            self.resolutions.clear()
                        try:
                            self._yt = pytube.YouTube(
                                self.url,
                                on_progress_callback=self._on_progress,
                                on_complete_callback=self._on_complete,
                            )
                            streams = self._yt.streams.filter(mime_type="video/mp4", progressive="True")
                        except Exception as e:
                            self.initialized.emit(False, str(e))
                            return
                        with self._mutex:
                            self.resolutions = [stream.resolution for stream in streams]
                        self.initialized.emit(True, "")
                
                    def download(self, resolution, directory):
                        threading.Thread(
                            target=self._download, args=(resolution, directory), daemon=True
                        ).start()
                
                    def _download(self, resolution, directory):
                        stream = self._yt.streams.get_by_resolution(resolution)
                        self.download_started.emit()
                        stream.download(directory)
                
                    def _on_progress(self, stream, chunk, bytes_remaining):
                        self.download_progress_changed.emit(
                            100 * (stream.filesize - bytes_remaining) // stream.filesize
                        )
                
                    def _on_complete(self, stream, filepath):
                        self.download_finished.emit()
                
                
                class MainWindow(QtWidgets.QMainWindow):
                    def __init__(self, parent=None):
                        super().__init__(parent)
                
                        self.le_url = QtWidgets.QLineEdit("http://youtube.com/watch?v=2lAe1cqCOXo")
                        self.lbl_error = QtWidgets.QLabel()
                        self.btn_search = QtWidgets.QPushButton("Search")
                        self.cmb_resolutions = QtWidgets.QComboBox()
                        self.le_directory = QtWidgets.QLineEdit("")
                        self.btn_download = QtWidgets.QPushButton("Download")
                        self.pgb_download = QtWidgets.QProgressBar()
                
                        central_widget = QtWidgets.QWidget()
                        self.setCentralWidget(central_widget)
                        lay = QtWidgets.QGridLayout(central_widget)
                        lay.addWidget(self.le_url, 0, 0)
                        lay.addWidget(self.btn_search, 0, 1)
                        lay.addWidget(self.cmb_resolutions, 1, 0)
                        lay.addWidget(self.le_directory, 1, 1)
                        lay.addWidget(self.btn_download, 1, 2)
                        lay.addWidget(self.pgb_download, 2, 0, 1, 3)
                
                        self.btn_download.setEnabled(False)
                
                        self._qpytube = None
                
                        self.btn_search.clicked.connect(self.handle_search_clicked)
                        self.btn_download.clicked.connect(self.handle_download_clicked)
                
                    def handle_search_clicked(self):
                        self.cmb_resolutions.clear()
                        self.btn_search.setEnabled(False)
                        self.btn_download.setEnabled(False)
                        self.lbl_error.clear()
                        self._qpytube = QPyTube(self.le_url.text())
                        self._qpytube.initialized.connect(self.handle_initialized)
                        self._qpytube.download_progress_changed.connect(self.pgb_download.setValue)
                        self._qpytube.download_started.connect(self.handle_download_started)
                        self._qpytube.download_finished.connect(self.handle_download_finished)
                
                    @QtCore.pyqtSlot(bool, str)
                    def handle_initialized(self, status, error=""):
                        if status:
                            self.cmb_resolutions.addItems(self._qpytube.resolutions)
                            self.btn_download.setEnabled(True)
                        else:
                            self.lbl_error.setText(error)
                        self.btn_search.setEnabled(True)
                
                    def handle_download_clicked(self):
                        self._qpytube.download(
                            self.cmb_resolutions.currentText(), self.le_directory.text()
                        )
                        self.btn_search.setEnabled(False)
                        self.btn_download.setEnabled(False)
                        self.le_directory.setEnabled(False)
                
                    def handle_download_started(self):
                        self.lbl_error.clear()
                        print("started")
                
                    def handle_download_finished(self):
                        self.pgb_download.setValue(100)
                        self.btn_search.setEnabled(True)
                        self.btn_download.setEnabled(True)
                        self.le_directory.setEnabled(True)
                        print("finished")
                
                
                def main(args):
                    app = QtWidgets.QApplication(args)
                
                    w = MainWindow()
                    w.show()
                
                    app.exec_()
                
                
                if __name__ == "__main__":
                    main(sys.argv)
                

                这篇关于GUI在下载PyQt5和Pytube时冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                上一篇:如何解决使用Pool.map()进行多处理时的内存问题? 下一篇:没有了

                相关文章

                <small id='k1DFp'></small><noframes id='k1DFp'>

                <i id='k1DFp'><tr id='k1DFp'><dt id='k1DFp'><q id='k1DFp'><span id='k1DFp'><b id='k1DFp'><form id='k1DFp'><ins id='k1DFp'></ins><ul id='k1DFp'></ul><sub id='k1DFp'></sub></form><legend id='k1DFp'></legend><bdo id='k1DFp'><pre id='k1DFp'><center id='k1DFp'></center></pre></bdo></b><th id='k1DFp'></th></span></q></dt></tr></i><div id='k1DFp'><tfoot id='k1DFp'></tfoot><dl id='k1DFp'><fieldset id='k1DFp'></fieldset></dl></div>
              • <legend id='k1DFp'><style id='k1DFp'><dir id='k1DFp'><q id='k1DFp'></q></dir></style></legend>
              • <tfoot id='k1DFp'></tfoot>

                    • <bdo id='k1DFp'></bdo><ul id='k1DFp'></ul>