我对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函数。
问题是,在fileIsReady完成读取XML文件并返回空映射之前执行getSearchList。
据我所知,构造函数不应该在fileIsReady()
完成工作之前完成。因此,不应该提前调用getSearchList()。
我的两个问题:
提前多多感谢!
答案 0 :(得分:3)
首先,您需要了解信号和插槽的基本概念。
进行连接后,每次发出信号时都会调用插槽。
将信号连接到插槽后,connect()
函数返回。它不会等待发出信号。
在您的XMLParser构造函数中,您的connect()
函数会注册:&#34;当发出finished()
信号时,运行fileIsReady()
函数&#34;。
现在,回答你的问题。
- 为什么我的程序在功能没有完成阅读时进展。
醇>
因为在构造函数代码中,在将信号连接到插槽后要求构造函数完成。您没有要求它等待下载完成。
然后,在不等待finished()信号的情况下调用getSearchList()。因此,在fileIsReady()之前调用getSearchList()。
- 如何进行第二次通话&#34; getSearchList&#34;等待?
醇>
就像MrEricSir所说,你不应该让它等待! (想想看:如果你失去了互联网连接并且无法完成下载文件会怎么样?答案是,你的程序会冻结,因为它会永远等待。这很糟糕。)
构建XMLParser后不要立即调用getSearchList()
。相反,让XMLParser发出一个&#34; finishedParsing()&#34;完成解析XML文件时发出信号。然后,进行另一个信号槽连接:将finishedParsing()信号连接到调用getSearchList()的插槽。
答案 1 :(得分:1)
如何进行第二次电话
getSearchList
等待?
你不是!相反,只需将期望XML
文件的任何代码移动到您已定义的fileIsReady()
广告位中。这样,你的程序在等待下载完成时就不会锁定(这是异步编程的全部内容。)
答案 2 :(得分:1)
所以,我找到了一个使用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();
}