Как разрешить QNetworkAccessManager запускать HTTP-запросы в отдельном потоке

Я хочу, чтобы QNetworkAccessManager запускал HTTP-запросы в отдельном потоке. В настоящее время в QT4.6 он работает в том же потоке, что приводит к зависанию моего браузера. Эта функция недавно появилась в QT 4.8, но теперь я не могу переключиться на QT 4.8. поэтому я хочу реализовать это в QT 4.6 для QNetworkAccessManager.

Может ли кто-нибудь помочь мне в этом?


person ashmish2    schedule 03.12.2011    source источник
comment
Вы не можете сделать свой собственный отдельный QThread ?   -  person Basile Starynkevitch    schedule 03.12.2011
comment
Да, но я должен отделить все HTTP-вызовы в этом потоке. как это сделать? Я мало знаю о внутренностях QT   -  person ashmish2    schedule 03.12.2011


Ответы (2)


Есть более чем пара способов добиться желаемого.

Во-первых, убедитесь, что вы правильно используете QNetworkAccessManager. По умолчанию HTTP-запросы, такие как:

QNetworkAccessManager *manager= new QNetworkAccessManager(this);
manager->post(QNetworkRequest(QUrl("http://www.example.com/")));

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

Один из способов, который я использую для обеспечения того, чтобы запросы выполнялись в отдельных потоках, — это создание всего QObject/QWidget для моего QNetworkAccessManager следующим образом:

(Заголовок)

class Manager : public QWidget
{
    Q_OBJECT

public:
    Manager(QWidget *parent=0);
    QNetworkAccessManager *manager;
private slots:
    void replyFinished(QNetworkReply* data);
};

//... ... ...
//Later in the main thread declaration
//... ... ...

class MainBrowserWindow : public QWidget
{
     //.... ... .. .. 
     //Other stuff for the main window

     Manager managingWidget;
     //this ensures that a new thread will be created and initialized
     //alongside our MainBrowserWindow object (which is initialized in main.cpp)

};

(Реализация)

Manager::Manager(QWidget *parent): QWidget (parent){
    //Initialize the widget here, set the geometry title and add other widgets
    //I usually make this a QWidget so that it can double as a
    //pop-up progress bar.

    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*)));
}

Теперь вы можете совершать вызовы вашего объекта-менеджера из реализации вашего главного окна с помощью таких вызовов, как:

managingWidget.manager->post()

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

person buster    schedule 05.12.2011

Прочтите о потоках в Qt и создайте свой собственный поток, который получает сигнал для каждого URL. для обработки и отправки некоторого сигнала обратно в основной поток при обработке ответа HTTP.

person Basile Starynkevitch    schedule 03.12.2011