2012-10-01 4 views
0

다른 URL을 사용하는 GUI 프로그램을 만들기 위해 Qt 작성자와 협력 중이며 html 코드를 다운로드하여 표시합니다.Qt 네트워크 업데이트 후 업데이트

사용자는 다른 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 - 아주 간단합니다. 입력 된 웹 사이트에서 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 - 응답이 수신되면, 그것은 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; 
} 

의 HTML이 할 수있는 쉬운 방법이 있나요 저장 응답이 수신되면 str의 값을 MainWindow 클래스로 보내거나 응답이 수신 될 때까지 텍스트 영역을 업데이트하기 위해 onclick 함수가 기다릴 수있는 방법이 있습니까?

답변

3

확실히 onClick() 함수에서 회신을 기다리지 않으려 고합니다. 네트워크 요청이 올 때까지 프로그램이 응답하지 않게됩니다 ("영원히"걸릴 수 있습니다).

이것을 공격하는 한 가지 방법은 HtmlManager 클래스에 신호를 추가하는 것입니다. 뭔가 stringReceived이라고 할 수 있습니다. 그런 다음 메인 윈도우 클래스에서 다음과 같은 행을 추가하면됩니다.

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

게시 한 코드를 어떻게 변경하여 합법적으로 만들 수 있습니까? html 객체와 ui-> textbrowser는 다른 유형입니다. 작동하도록 변경하려면 어떻게해야합니까? –

+0

두 가지 유형이 모두 괜찮습니다. 둘 다 QObject에서 파생됩니다. QObject :: connect에 대한 문서는 [here] (http://qt-project.org/doc/qt-4.8/qobject.html#connect)입니다. 첫 번째와 세 번째 인수는 QObject 포인터입니다. –

+0

그들은 위의 코드에서 서로 다른 유형 이었지만이를 수정했습니다. 이제 제안한 코드를 사용할 때 링커 오류가 발생합니다. LNK2005 : htmlmanager.obj에 이미 정의 된 "protected : void __thiscall HtmlManager :: stringReceived (class QString)"(? stringReceived @ HtmlManager @@ IAEXVQString @@@ Z)이 문제의 원인은 무엇입니까? –

0

QNetworkAccessManager는 동기식 또는 차단 방식을 제공하지 않습니다. 응답이 수신 될 때까지 기다리려면 응답 완료 신호가 호출 될 때까지 로컬 이벤트 루프에서 대기해야합니다. http://doc.qt.digia.com/qq/qq27-responsive-guis.html

가 QNetworkAccessManager를 사용하는 예를 보여 주었다 "로컬 이벤트 루프에서 대기"섹션에서 :

동기 하나에 비동기 작업을 전환은 다음 링크를 참조하십시오. 타임 아웃 및 로컬 이벤트 루프와 동일한 접근 방식을 사용할 수 있습니다.

관련 문제