Qt QNetworkAccessManager 和插槽不起作用
Posted
技术标签:
【中文标题】Qt QNetworkAccessManager 和插槽不起作用【英文标题】:Qt QNetworkAccessManager and Slot not working 【发布时间】:2015-03-28 09:17:47 【问题描述】:我是 C++ 的初学者,我正在尝试使用 http 请求从网站检索数据并将数据下载到文件中。
我正在使用这些课程:
QMainWindow QtNetwork/QNetworkAccessManager QtNetwork/QNetworkRequest QtNetwork/QNetworkReply 网址
问题是文件已创建,但文件中没有数据,我收到一个我不理解的错误。我通过论坛搜索发现了一些类似的问题,但由于我是初学者所以不明白。请帮助我这是一个学校项目,我真的被困在这里了。
这里是 httpWindow.h 代码
#ifndef HTTPWINDOW_H
#define HTTPWINDOW_H
#include <QMainWindow>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QUrl>
#include <QString>
class QFile;
namespace Ui
class httpWindow;
class httpWindow : public QMainWindow
Q_OBJECT
public:
explicit httpWindow(QWidget *parent = 0);
~httpWindow();
void request(QUrl url);
private slots:
void downloadFile();
void httpFinished();
void httpReadyRead();
private:
Ui::httpWindow *ui;
QUrl url;
QNetworkAccessManager *manager;
QNetworkRequest requete;
QNetworkReply *reply;
QFile *file;
int httpGetId;
bool httpRequestAborted;
;
#endif // HTTPWINDOW_H
这里是httpwindow.cpp
#include <QtWidgets>
#include <qnetwork.h>
#include <QString>
#include "httpwindow.h"
#include "ui_httpwindow.h"
httpWindow::httpWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::httpWindow)
ui->setupUi(this);
downloadFile();
httpWindow::~httpWindow()
delete ui;
void httpWindow::request(QUrl url)
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished()),
this, SLOT(httpFinished()));
//requete.setUrl(QUrl("http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide"));
requete.setUrl(url);
reply = manager->get(requete);
connect(reply, SIGNAL(&reply::readyRead()), this, SLOT(httpReadyRead()));
void httpWindow::downloadFile()
QMessageBox msg ;
QUrl url("http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide") ;
qDebug() << url.toString();
QFileInfo fileInfo(url.path());
//msg.setText("fileInfo = " + fileInfo);
QString fileName = "C:\\testQt\\" + fileInfo.fileName();
msg.setText("fileName = " + fileName);
if (fileName.isEmpty())
fileName = "C:\testQt\fichier.html";
msg.setText(" création d'un nouveau fichier fichier.html ");
if (QFile::exists(fileName))
QFile::remove(fileName);
return;
file = new QFile(fileName);
msg.setText(" QFile::exists(fileName) == true , file : ");
if (!file->open(QIODevice::WriteOnly))
delete file;
file = 0;
return;
// schedule the request
httpRequestAborted = false;
request(url);
void httpWindow::httpFinished()
if (httpRequestAborted)
if (file)
file->close();
file->remove();
delete file;
file = 0;
reply->deleteLater();
return;
file->flush();
file->close();
QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (reply->error())
file->remove();
// QMessageBox::information(this, tr("HTTP"),
// tr("Download failed: %1.")
// .arg(reply->errorString()));
// downloadButton->setEnabled(true);
else if (!redirectionTarget.isNull())
QUrl newUrl = url.resolved(redirectionTarget.toUrl());
// if (QMessageBox::question(this, tr("HTTP"),
// tr("Redirect to %1 ?").arg(newUrl.toString()),
// QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
url = newUrl;
reply->deleteLater();
file->open(QIODevice::WriteOnly);
file->resize(0);
request(url);
return;
reply->deleteLater();
reply = 0;
delete file;
file = 0;
void httpWindow::httpReadyRead()
// this slot gets called every time the QNetworkReply has new data.
// We read all of its new data and write it into the file.
// That way we use less RAM than when reading it at the finished()
// signal of the QNetworkReply
if (file)
file->write(reply->readAll());
这里是main.cpp代码
#include "httpwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
QApplication a(argc, argv);
httpWindow w;
w.show();
return a.exec();
错误:
can't find linker symbol for virtual table for `QMessageBox' value
found `RGB_MASK' instead
can't find linker symbol for virtual table for `QMessageBox' value
found `RGB_MASK' instead
"http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide"
QObject::connect: No such signal QNetworkAccessManager::finished() in ..\ppe3_trading_test\httpwindow.cpp:24
QObject::connect: (receiver name: 'httpWindow')
QObject::connect: No such signal QNetworkReplyHttpImpl::&reply::readyRead() in ..\ppe3_trading_test\httpwindow.cpp:31
QObject::connect: (receiver name: 'httpWindow')
请帮帮我,这对我的学业非常重要。
【问题讨论】:
【参考方案1】:connect(reply, SIGNAL(&reply::readyRead()), this, SLOT(httpReadyRead()));
你把旧语法和新语法混在一起了,应该是
connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
或者更好的是使用新语法(仅限 Qt5):
connect(reply, &QNetworkReply::readyRead, this, &httpWindow::httpReadyRead);
QNetworkAccessManager
没有finished()
信号它有finished(QNetworkReply*)
信号,请阅读文档。
【讨论】:
为什么不推荐新语法?它更有帮助,因为可以在编译时检测到很多信号/插槽错误。 @SimonWarta 唯一的原因是我不习惯,但你说得对,我会把它添加到答案中。以上是关于Qt QNetworkAccessManager 和插槽不起作用的主要内容,如果未能解决你的问题,请参考以下文章
QT 从 QWebView 的 QNetworkAccessManager 读取数据
使用 QNetworkAccessManager 的 Qt 控制台应用程序