You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySide6中QNetworkManager与QNetworkReply信号未触发问题求助

PySide6中QNetworkReply信号不触发问题排查与修复

核心问题:QNetworkAccessManager被提前销毁

在load_img_from_url函数中,manager = QtNetwork.QNetworkAccessManager(None)创建的是局部变量,函数执行完成后该变量会被Python垃圾回收机制回收。而网络请求属于异步操作,请求还未完成时manager就已销毁,导致关联的QNetworkReply对象无法正常工作,自然不会触发finished、errorOccurred等信号。

修复方案1:将QNetworkAccessManager设为类成员变量

把manager作为TestWindow的实例变量,确保其生命周期与窗口一致,避免被提前回收:

from typing import Callable
import PySide6.QtNetwork as QtNetwork
from PySide6 import QtCore, QtGui, QtWidgets
import sys


def load_img_from_url(manager, url_str, callback):
    # type: (QtNetwork.QNetworkAccessManager, str, Callable[[QtGui.QImage], None]) -> None

    url = QtCore.QUrl(url_str)
    if url.isValid():
        QtCore.qDebug("load_img_from_url: url is valid => " + url.url())
        
        QtNetwork.QNetworkProxyFactory.setUseSystemConfiguration(True)
        request = QtNetwork.QNetworkRequest(url)
        
        def handle_reply(reply):
            # type: (QtNetwork.QNetworkReply) -> None
            print("reply object => ", reply)

            if reply.error() == QtNetwork.QNetworkReply.NetworkError.NoError:
                print("QNetworkReply No error")
                response_data = reply.readAll()
                image = QtGui.QImage()
                if image.loadFromData(response_data):
                    QtCore.qDebug("load_img_from_url: Image Loaded")
                    if callable(callback):
                        callback(image)
                else:
                    QtCore.qDebug("load_img_from_url: Image Not Loaded")

            else:
                print("QNetworkReply Error!")
            reply.deleteLater()  # 处理完成后释放reply资源

        manager.finished.connect(lambda r: print("manager reply", r))
        
        reply = manager.get(request)

        reply.finished.connect(handle_reply)
        reply.redirected.connect(lambda r: print("redirected", r))

        def handle_error(error):
            print("QNetworkReply Error")
            print(error)
            reply.deleteLater()
            
        reply.errorOccurred.connect(handle_error)

        QtCore.qDebug("load_img_from_url: QNetworkReply isFinished? "+ str(reply.isFinished()))

class TestWindow(QtWidgets.QMainWindow):
    def __init__(self, parent) -> None:
        super().__init__(parent)
        self.manager = QtNetwork.QNetworkAccessManager(self)  # 将manager设为类成员,父对象绑定窗口
        load_img_from_url(self.manager, "https://cdn.pixabay.com/photo/2014/06/03/19/38/road-sign-361514_960_720.png", None)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    widget = TestWindow(None)
    widget.show()

    sys.exit(app.exec())

修复方案2:给QNetworkAccessManager设置长期存在的父对象

如果不想修改函数结构,可以给manager指定QApplication实例作为父对象,确保其生命周期与应用一致:

在load_img_from_url函数中修改manager的创建代码:

manager = QtNetwork.QNetworkAccessManager(QtWidgets.QApplication.instance())

额外注意事项

  • 处理完QNetworkReply后,调用reply.deleteLater()释放资源,避免内存泄漏。
  • 代码中已做url.isValid()校验,URL有效性部分无需调整。

内容的提问来源于stack exchange,提问作者razor_chk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:23:13