Qt Update после ответа по сети

Я работаю с создателем Qt, чтобы создать программу с графическим интерфейсом, которая принимает разные URL-адреса и загружает и отображает HTML-код.

Пользователь может добавлять различные URL-адреса в список виджетов. Затем пользователь может выбрать конкретный URL-адрес и загрузить HTML, который будет отображаться рядом со списком URL-адресов.

У меня проблема с обновлением текстовой области после получения ответа.

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 ждать обновления текстовой области до получения ответа?

0

Решение

Вы определенно не хотите ждать ответа в функции onClick (). Это приведет к тому, что ваша программа не будет отвечать на запросы до тех пор, пока не поступит сетевой запрос (что вполне может занять «навсегда»).

Один из способов атаковать это — добавить сигнал в ваш класс HtmlManager. Что-то может быть названо stringReceived, Затем в вашем классе mainwindow вам просто нужно добавить такую ​​строку:

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

Другие решения

QNetworkAccessManager не предоставляет синхронный или блокирующий подход. Если вы хотите подождать, пока ответ не будет получен, вам нужно подождать в локальном цикле событий до тех пор, пока не завершится ответный сигнал.

Смотрите следующую ссылку для превращения асинхронной операции в синхронную:
http://doc.qt.digia.com/qq/qq27-responsive-guis.html

В разделе «Ожидание в локальном цикле событий» они показали пример использования QNetworkAccessManager. Вы можете использовать тот же подход с тайм-аутом и локальным циклом событий.

0

По вопросам рекламы [email protected]