Qt 5.10中按钮触发HTTP请求时信号未发射问题求助
问题原因分析
这个问题的核心是对象生命周期的差异,咱们拆解来看:
在
main()函数里,Request req是函数作用域内的局部变量,但它的生命周期会持续到app.exec()执行完毕(也就是整个应用退出时)。HTTP请求是异步操作,当服务器响应返回时,这个req对象还存活,所以能正常发射信号让你接收到。但在
startRequest()函数里,Request req是栈上的临时局部对象:函数执行到req.Connector();后很快就结束了,这个req会被立刻销毁(栈变量的特性)。虽然Wireshark抓到了请求和响应,但等响应回来时,req已经不存在了,自然没法触发信号。
解决方案
你需要延长Request对象的生命周期,让它能存活到响应返回的时刻,这里有两种常用的做法:
把
Request设为MainWidget的成员变量:
在MainWidget类里声明Request成员,这样它的生命周期和窗口一致,只要窗口没关闭,对象就会一直存在:class MainWidget : public QWidget { QLineEdit *url_input = new QLineEdit(this); QToolBar *tool_bar = new QToolBar; Request req; // 作为类成员变量 public: MainWidget(QWidget *parent = 0); void setToolBar(); void startRequest(); }; void MainWidget::startRequest () { req.Connector(); // 调用成员变量的方法 }动态分配
Request对象(配合智能指针或父对象管理):
如果每次请求都需要新的实例,可以用动态分配,记得在响应处理完成后销毁对象,或者把MainWidget设为父对象让Qt自动管理:void MainWidget::startRequest () { Request *req = new Request(this); // 以MainWidget为父对象,自动回收 connect(req, &Request::yourResponseSignal, this, [=](/* 响应参数 */){ // 在这里处理服务器返回的响应 req->deleteLater(); // 处理完成后销毁对象 }); req->Connector(); }
额外提示
Qt的异步操作(比如网络请求)完全依赖对象的存活状态,所以一定要确保发起请求的对象在整个异步流程结束前不会被销毁。如果你底层用的是QNetworkAccessManager这类Qt网络组件,也要注意同样的生命周期问题哦。
内容的提问来源于stack exchange,提问作者NinuX
相关产品推荐
相关产品推荐

