Я получаю несколько сигналов loadFinished
, когда пытаюсь загрузить QWebPage
, и я не уверен, что вызывает проблему. Было несколько других вопросов, которые, казалось, ссылались на ту же проблему, но решения не сработали для меня:
- QtWebPage - loadFinished() вызывается несколько раз
- Signal QWebPage::loadFinished(bool) возвращается дважды?
В первом вопросе ответ был "подключать сигналы к слотам только один раз", но я это уже делаю. Ответ на второй вопрос предполагает, что я должен подключаться к сигналу loadFinished
фрейма, но я просто не получаю нужные данные когда это будет сделано.
Я пытаюсь загрузить несколько страниц:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QList<QUrl> urls;
urls.append(QUrl("http://www.useragentstring.com/pages/Chrome/"));
urls.append(QUrl("http://www.useragentstring.com/pages/Firefox/"));
urls.append(QUrl("http://www.useragentstring.com/pages/Opera/"));
urls.append(QUrl("http://www.useragentstring.com/pages/Internet Explorer/"));
urls.append(QUrl("http://www.useragentstring.com/pages/Safari/"));
foreach(QUrl url, urls)
{
UA* ua = new UA();
QWebPage* page = new QWebPage();
//QObject::connect(page, SIGNAL(loadFinished(bool)), ua, SLOT(pageLoadFinished(bool)));
QObject::connect(page->mainFrame(), SIGNAL(loadFinished(bool)), ua, SLOT(frameLoadFinished(bool)));
// Load the page
page->mainFrame()->load(url);
}
return app.exec();
}
Класс, обрабатывающий сигналы, выглядит так:
class UA:public QObject
{
Q_OBJECT
private:
int _numPageLoadSignals;
int _numFrameLoadSignals
public:
UA()
{
_numPageLoadSignals = 0;
_numFrameLoadSignals = 0;
}
~UA(){}
public slots:
void pageLoadFinished(bool ok)
{
_numPageLoadSignals++;
QWebPage * page = qobject_cast<QWebPage *>(sender());
if(ok && page)
{
qDebug() << _numPageLoadSignals << " loads "
<< page->mainFrame()->documentElement().findAll("div#liste ul li a").count()
<< " elements found on: " << page->mainFrame()->requestedUrl().toString();
}
}
void frameLoadFinished(bool ok)
{
_numFrameLoadSignals++;
QWebFrame * frame = qobject_cast<QWebFrame *>(sender());
if(ok && frame)
{
qDebug() << _numFrameLoadSignals << " loads "
<< frame->documentElement().findAll("div#liste ul li a").count()
<< " elements found on: " << frame->requestedUrl().toString();
}
}
};
Вот результат подключения только к сигналу loadFinished
фрейма:
1 loads 0 elements found on: "http://www.useragentstring.com/pages/Safari/"
1 loads 0 elements found on: "http://www.useragentstring.com/pages/Chrome/"
1 loads 0 elements found on: "http://www.useragentstring.com/pages/Opera/"
1 loads 0 elements found on: "http://www.useragentstring.com/pages/Firefox/"
1 loads 241 elements found on: "http://www.useragentstring.com/pages/Internet Explorer/"
Вот результаты, когда я подключаюсь к сигналу loadFinished
страницы:
1 loads 0 elements found on: "http://www.useragentstring.com/pages/Safari/"
1 loads 0 elements found on: "http://www.useragentstring.com/pages/Chrome/"
1 loads 0 elements found on: "http://www.useragentstring.com/pages/Firefox/"
1 loads 0 elements found on: "http://www.useragentstring.com/pages/Internet Explorer/"
2 loads 576 elements found on: "http://www.useragentstring.com/pages/Safari/"
2 loads 782 elements found on: "http://www.useragentstring.com/pages/Chrome/"
2 loads 241 elements found on: "http://www.useragentstring.com/pages/Internet Explorer/"
2 loads 1946 elements found on: "http://www.useragentstring.com/pages/Firefox/"
3 loads 241 elements found on: "http://www.useragentstring.com/pages/Internet Explorer/"
3 loads 1946 elements found on: "http://www.useragentstring.com/pages/Firefox/"
3 loads 782 elements found on: "http://www.useragentstring.com/pages/Chrome/"
1 loads 964 elements found on: "http://www.useragentstring.com/pages/Opera/"
3 loads 576 elements found on: "http://www.useragentstring.com/pages/Safari/"
Я не понимаю такого поведения, почему иногда я получаю соответствующий контент, а иногда нет. Если я подключусь к сигналу loadFinished
страницы, то в конечном итоге я получу контент, но я не знаю, когда это произойдет на самом деле. Как узнать, что моя страница фактически завершила загрузку?
Обновлять
Я предполагаю, что большая часть моего контента будет доставлена менее чем за 3 секунды, поэтому я придумал обходной путь: я установил событие таймера, чтобы сигнализировать UA::loadFinished
через 3 секунды после получения первого сигнала loadFinished
от QWebPage
. Это не очень красиво и неэффективно, но в данной ситуации работает.