首先说一下问题背景:
这几天闲来无事,打算用有道翻译API做一个基于命令行的在线翻译工具。
先来看看代码结构:
就一个类MyQObject,继承自QObject。类中主要通过QNetworkAccessManager和QNetworkReply两个类来实现发送请求和读取服务器返回的数据。
main函数就是构造了MyQObject的对象进行发送请求。
在写的过程中发现两个问题。
第一个问题,每次main函数中的MyQObject对象在调用getData函数后就直接返回了,并没有读取返回的数据。
第二个问题,在第一个问题解决后,生成Release,在终端中运行时能够较好的获取到数据,并使用exit(0)来结束程序,可是程序在退出时总是会显示“QWaitCondition: Destroyed while threads are still waiting”这行。看意思是,强制结束了还在运行的线程。
先看第一个问题:
经过google后,知道是因为QNetworkAccessManager类是异步进行的,而这里我需要的是同步。可是QNetworkAccessManager本身并未提供同步的功能。两个方法,一是使用QTcpSocket来做,可是又懒得改代码,就没有做;二是,建立另一个事件循环,等读取完数据后,再退出循环。
实现代码片段如下:
QEventLoop eventLoop;
connect(manager,QNetworkAccessManager::finished,&eventLoop, &QEventLoop::quit);
reply = manager->get(request);
connect(reply, SIGNAL(finished()), this, SLOT(readyReadReply()));
eventLoop.exec();
再来看看第二个问题:
先来看看造成这个问题的代码片段:
int main(int argc, char *argv[])
{
......
MyQObject *myobj=new MyQObject();
......
if(argc==2)
{
myobj->setargdata(keyfrom,key,QString(argv[1]),true);
myobj->getData();
exit(0);
}
return a.exec();
}
能够正确获取数据,功能都实现了,但是就是在exit(0)后出现了图片中的那行。
依然是google,最终在stackoverflow找到了解决方法。下面贴出方法:
if(argc==2)
{
myobj->setargdata(keyfrom,key,QString(argv[1]),true);
QObject::connect(myobj,SIGNAL(broadexit()),&a,SLOT(quit()));
QTimer::singleShot(0,myobj,SLOT(getData()));
}
broadexit()是MyQObject的信号,在MyQObject对象读取完数据后发出该信号,main函数接收到该信号后就调用程序的quit函数退出。
问题解决了,stackoverflow上也没说清楚问题原因,只说大概是因为在程序进入事件循环之前,也就是return a.exec()执行前,退出造成的。
贴出原文地址:http://stackoverflow.com/questions/29264782/proper-way-to-close-qcoreapplication