0

Qt クリエーターと協力して、さまざまな URL を取り込み、html コードをダウンロードして表示する GUI プログラムを作成しています。

ユーザーは、さまざまな URL を listWidget に追加できます。次に、ユーザーは特定の 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 - 非常に簡単です。入力された Web サイトから 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";
    }

}

htmlmanager.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 関数がテキスト領域の更新を待機する方法はありますか?

4

2 に答える 2

3

onClick() 関数で応答を待ちたくないことは間違いありません。これにより、ネットワーク要求が来るまでプログラムが応答しなくなります (これには「永遠に」かかる可能性があります)。

これを攻撃する 1 つの方法は、HtmlManager クラスにシグナルを追加することです。と呼ばれるものがありstringReceivedます。次に、メインウィンドウ クラスに次のような行を追加するだけです。

connect(html, SIGNAL(stringReceived(QString)), ui->textBrowser, SLOT(setText(QString));
于 2012-10-01T00:37:22.427 に答える
0

QNetworkAccessManagerは、同期またはブロッキングアプローチを提供しません。応答が受信されるまで待機する場合は、応答終了信号が呼び出されるまでローカルイベントループで待機する必要があります。

非同期操作を同期操作に変換するには、次のリンクを参照してください。http: //doc.qt.digia.com/qq/qq27-sensitive-guis.html

「ローカルイベントループでの待機」のセクションでは、QNetworkAccessManagerを使用した例を示しています。タイムアウトとローカルイベントループで同じアプローチを使用できます。

于 2012-10-02T06:39:46.410 に答える