Qt 中的异步函数调用
Asynchronous function calls in Qt
我对Qt
和编程很陌生,面临着一个我找不到解决方案的问题。
我想从在线XML文件中读取一些信息并将其发送到我的主程序。
为此,我创建了一个类 XMLParser,并将以下内容添加到构造函数中:
XMLParser::XMLParser(QString searchstring)
{
QNetworkAccessManager *manager2 = new QNetworkAccessManager(this);
reply = manager2->get(QNetworkRequest(QUrl("http://www.boardgamegeek.com/xmlapi/search?search="+searchstring)));
XMLParser::connect(reply, SIGNAL(finished()),
this, SLOT(fileIsReady()) );
}
fileIsReady
填充 QMap 并将其存储为私有类成员。
在第二节课上,我打电话
XMLParser *xmlpars = new XMLParser(input_gamename->text());
QMap<QString, int> searchResults = xmlpars->getSearchList();
getSearchList是一个简单的getter函数。
问题是,getSearchList 是在 fileIsReady 完成读取 XML 文件并返回空映射之前执行的。据我了解,构造函数不应该在fileIsReady()
完成其工作之前完成。因此,getSearchList() 不应该被提前调用。
我的两个问题:
- 为什么我的程序在函数没有完成读取时进行。
- 如何让第二个调用"getSearchList"等待?
提前非常感谢!
首先,您需要了解信号和插槽的基本概念。
建立连接后,每次发出信号时都会调用该插槽。
将信号连接到插槽后,connect()
功能返回。它不会等待信号发出。
在 XMLParser 构造函数中,connect()
函数注册以下内容:"发出finished()
信号时,运行 fileIsReady()
函数"。
现在,回答您的问题。
因为在构造函数
- 为什么我的程序在函数没有完成读取时进行。
代码中,您要求构造函数在将信号连接到插槽后完成。您没有要求它等待下载完成。
然后,你调用getSearchList(),而不等待done()信号。因此,getSearchList() 在 fileIsReady() 之前被调用。
- 如何让第二个调用"getSearchList"等待?
就像埃里克先生说的,你不应该要求它等待!(想一想:如果您失去互联网连接并且无法完成文件下载,会发生什么?答案是,你的程序会冻结,因为它会永远等待。这很糟糕。
不要在构造 XMLParser(getSearchList()
)后立即调用。相反,让 XMLParser 在完成解析 XML 文件时发出"finishParsing()"信号。然后,建立另一个信号槽连接:将完成的Parsing()信号连接到调用getSearchList()的时隙。
因此,我使用QEventLoop找到了解决方案。但据我所知,这不是推荐的。还有其他解决方案吗?以及为什么使用QEventLoop是坏习惯(这是我从StackOverflow的其他答案中读到的)。
XMLParser::XMLParser(QString searchstring)
{
QNetworkAccessManager *manager2 = new QNetworkAccessManager(this);
reply = manager2->get(QNetworkRequest(QUrl("http://www.boardgamegeek.com/xmlapi/search?search="+searchstring)));
QEventLoop loop;
XMLParser::connect(reply, SIGNAL(finished()),
this, SLOT(fileIsReady()) );
XMLParser::connect(this, SIGNAL(finishedReading()),
&loop, SLOT(quit()));
loop.exec();
}
如何在等待
getSearchList
进行第二次呼叫?
你没有!相反,只需将任何希望将XML
文件下载到已定义的fileIsReady()
槽的代码即可。这样,您的程序在等待下载完成时就不会锁定(这是异步编程的全部意义所在)。
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- 如何在 std::future 的向量中调用异步函数
- 如何从 dart 对用 C/C++ 编写的函数进行异步调用
- C++中的异步函数调用
- Qt 中的异步函数调用
- 如何避免在调用异步函数进行 lambda 回调时出现额外的副本
- 对ReadFile函数的异步调用返回6个错误代码
- 异步函数调用的参数生存期
- std::成员函数的异步调用
- 提升:触发并忘记异步函数调用