为了账号安全,请及时绑定邮箱和手机立即绑定

如何通过 QNetworkAccessManager 等待两个异步下载完成?

如何通过 QNetworkAccessManager 等待两个异步下载完成?

扬帆大鱼 2023-10-26 16:37:56
===总结=============================================我使用 QNetworkAccessManager 和 QNetworkRequests 同时下载两个图像。我如何确定两次下载已完成?===详细说明=================================我有两个图像的 URL,我想异步下载它们。为此,我初始化 QNetworkAccessManager 并使用两个 QNetworkRequest。完成后,每个请求都会将图像的内容写入文件中。问题是两个请求彼此一无所知,因此无法验证另一个请求是否已完成。您能告诉我如何等待这两个请求完成吗?这是完整的代码:import sysfrom PyQt5.QtCore import QUrl, QFile, QIODevicefrom PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequestfrom PyQt5.QtWidgets import QApplication, QWidgetclass MainWindow(QWidget):    def __init__(self):        super(MainWindow, self).__init__()        img_url1 = "https://somesite.com/image1.jpg"        img_url2 = "https://somesite.com/image2.jpg"        self.downloader = QNetworkAccessManager()        self.requests = []        self.temp_files = []        for index, mediafile_url in enumerate([img_url1, img_url2]):            self.requests.append(self.downloader.get(QNetworkRequest(QUrl(mediafile_url))))            request = self.requests[index]            self.temp_files.append(QFile(f'{mediafile_url.split("/")[-1]}'))            temp_file = self.temp_files[index]            request.finished.connect(lambda *args, r=request, tf=temp_file: self.download_image(r, tf))        self.show()    @staticmethod    def download_image(request, temp_file):        image_data = request.readAll()        temp_file.open(QIODevice.WriteOnly)        temp_file.write(image_data)        temp_file.close()app = QApplication(sys.argv)window = MainWindow()app.exec_()
查看完整描述

1 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

您必须创建一个跟踪下载的类:


from dataclasses import dataclass

import sys


from PyQt5.QtCore import pyqtSignal, QObject, QUrl, QFile, QIODevice

from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply

from PyQt5.QtWidgets import QApplication, QWidget



@dataclass

class DownloadRequest:

    url: QUrl

    filename: str



class DownloadManager(QObject):

    finished = pyqtSignal()


    def __init__(self, parent=None):

        super().__init__(parent)

        self._manager = QNetworkAccessManager()

        self._pending_downloads = 0


        self.manager.finished.connect(self.handle_finished)


    @property

    def manager(self):

        return self._manager


    @property

    def pending_downloads(self):

        return self._pending_downloads


    def download(self, requests):

        for request in requests:

            qrequest = QNetworkRequest(request.url)

            qrequest.setAttribute(QNetworkRequest.User, request.filename)

            self.manager.get(qrequest)

            self._pending_downloads += 1


    def handle_finished(self, reply):

        self._pending_downloads -= 1

        if reply.error() != QNetworkReply.NoError:

            print(f"code: {reply.error()} message: {reply.errorString()}")

        else:

            print("successful")

            filename = reply.attribute(QNetworkRequest.User)

            file = QFile(filename)

            if file.open(QIODevice.WriteOnly):

                file.write(reply.readAll())


        print(f"pending downloads {self.pending_downloads}")

        if self.pending_downloads == 0:

            self.finished.emit()



class MainWindow(QWidget):

    def __init__(self, parent=None):

        super().__init__(parent)


        self._manager = DownloadManager()

        self._manager.finished.connect(self.handle_finished)


        img_url1 = "https://docs.python.org/3/_static/py.png"

        img_url2 = "https://somesite.com/image2.jpg"


        request1 = DownloadRequest(QUrl(img_url1), img_url1.split("/")[-1])

        request2 = DownloadRequest(QUrl(img_url2), img_url2.split("/")[-1])


        self._manager.download([request1, request2])


    def handle_finished(self):

        print("finished")



def main():

    app = QApplication(sys.argv)

    window = MainWindow()

    window.show()

    app.exec_()



if __name__ == "__main__":

    main()


查看完整回答
反对 回复 2023-10-26
  • 1 回答
  • 0 关注
  • 145 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信