我希望 QNetworkAccessManager 在单独的线程中运行 HTTP 请求。目前在 QT4.6 中,它在同一个线程中运行,这会导致我的浏览器挂起。此功能最近在 QT 4.8 中引入,但现在我无法切换到 QT 4.8。因此我想在 QT 4.6 中为 QNetworkAccessManager 实现这个。
谁可以帮我这个事?
我希望 QNetworkAccessManager 在单独的线程中运行 HTTP 请求。目前在 QT4.6 中,它在同一个线程中运行,这会导致我的浏览器挂起。此功能最近在 QT 4.8 中引入,但现在我无法切换到 QT 4.8。因此我想在 QT 4.6 中为 QNetworkAccessManager 实现这个。
谁可以帮我这个事?
有多种方法可以实现您的愿望。
首先,确保您正确使用QNetworkAccessManager。默认情况下 HTTP 请求,例如:
QNetworkAccessManager *manager= new QNetworkAccessManager(this);
manager->post(QNetworkRequest(QUrl("http://www.example.com/")));
是异步生成的,但这并不一定意味着它们在自己的线程中。如果您进行大量此类调用,则可能会减慢包含线程的速度。
现在,我用来确保在单独的线程中发出请求的一种方法是为我的 QNetworkAccessManager 创建一个完整的 QObject/QWidget,如下所示:
(标题)
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 会自动将请求放置在它们自己的线程中。但这应该迫使操作系统将所有请求放在与主线程分开的线程中。
阅读Qt 中的线程,并创建自己的线程来接收每个要处理的 URL 的信号,并在处理 HTTP 回复时将一些信号发送回主线程。