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 读取数据

Qt同步QNetworkAccessManager获取

QT中的QNetworkAccessManager可靠连接

使用 QNetworkAccessManager 的 Qt 控制台应用程序

Qt无法打开包含文件:'QNetworkAccessManager':没有这样的文件或目录

在 Qt 中使用 QNetworkAccessManager 的持久连接