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
相关产品推荐
相关产品推荐

