网络回复后Qt更新

时间:2012-10-01 00:17:19

标签: c++ qt qnetworkaccessmanager

我正在与Qt创建者合作制作一个GUI程序,该程序会接收不同的URL并下载并显示html代码。

用户可以向listWidget添加不同的URL。然后,用户可以选择特定的URL并下载将显示在URL列表旁边的html。

我遇到的问题是在收到回复后让文本区域更新。

main.cpp - 基本上只显示窗口。

#include <QtGui/QApplication>
#include "mainwindow.h"
#include "htmlmanager.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.h - 非常直截了当。包含将用于从输入的网站请求html的对象html。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "htmlmanager.h"
#include <QString>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    HtmlManager html;

private slots:
    void on_addButton_clicked();
    void on_actionExit_triggered();
    void on_removeButton_clicked();
    void on_downloadButton_clicked();
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwindow.cpp - 这是问题的开始。如果你低头看“downloadButton_clicked()”函数,你会发现它通过发送请求来获取html。但是,在下一行之前未收到回复,因此文本字段设置为“”。

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_addButton_clicked()
{
    if(!ui->lineEdit->text().isEmpty())
    {
        ui->listWidget->addItem(ui->lineEdit->text());
    }
    else
    {
        qDebug() << "Input field is empty.";
    }
}

void MainWindow::on_actionExit_triggered()
{
    //doesn't do anything right now
}

void MainWindow::on_removeButton_clicked()
{
    if(ui->listWidget->currentItem()) //If an item is selected
    {
        delete ui->listWidget->currentItem();
    }
    else
    {
        qDebug() << "No selection";
    }
}

void MainWindow::on_downloadButton_clicked()
{
    if(ui->listWidget->currentItem()) //If an item is selected
    {
        html.fetch(ui->listWidget->currentItem()->text());
        ui->textBrowser->setText(html.str);
    }
    else
    {
        qDebug() << "No selection";
    }

}

htmlmaneger.h

#ifndef HTMLMANAGER_H
#define HTMLMANAGER_H

#include <QObject>
#include <QDebug>
#include <QtNetwork>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QString>


class HtmlManager : public QObject
{
    Q_OBJECT
    public:
        HtmlManager();
        void fetch(QString Url);
        QString str;

    public slots:
        void replyFinished(QNetworkReply* pReply);

    private:
        QNetworkAccessManager* m_manager;
};

#endif // HTMLMANAGER_H

htmlmanager.cpp - 收到回复后,它会将html存储在QString“str”中

#include "htmlmanager.h"

HtmlManager::HtmlManager()
{
    m_manager = new QNetworkAccessManager(this);
    connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
}
void HtmlManager::fetch(QString Url)
{
    m_manager->get(QNetworkRequest(QUrl(Url)));
    qDebug() << "Sending network request.";
}
void HtmlManager::replyFinished(QNetworkReply* pReply)
{
    qDebug() << "Recieved network reply.";
    QByteArray data=pReply->readAll();
    str = data;
}

收到回复后,是否有一种简单的方法可以将str的值发送到MainWindow类,或者是否有办法让onclick函数等到更新文本区域,直到收到回复为止?

2 个答案:

答案 0 :(得分:3)

您绝对不想在onClick()函数中等待回复。这将导致您的程序无响应,直到网络请求到来(这很可能“永远”)。

攻击此方法的一种方法是向HtmlManager类添加信号。有些东西可能被称为stringReceived。然后,在您的主窗口类中,您只需添加如下所示的行:

connect(html, SIGNAL(stringReceived(QString)), ui->textBrowser, SLOT(setText(QString));

答案 1 :(得分:0)

QNetworkAccessManager不提供同步或阻止方法。如果你想等到收到回复,你必须在本地事件循环中等待,直到回复完成信号被调用。

请参阅以下链接以将异步操作转换为同步操作: http://doc.qt.digia.com/qq/qq27-responsive-guis.html

在“等待本地事件循环”部分中,他们使用QNetworkAccessManager显示了一个示例。您可以使用与超时和本地事件循环相同的方法。