QNetworkAccessManager在QThread中被调用,因为是循环的

时间:2015-02-20 15:22:28

标签: get qthread qnetworkaccessmanager

我需要周期性地调用Web请求,因此,当然,简单的方法就是创建一个线程并调用我的请求然后休眠。 问题是我编写了我的代码,它基本上有效。当我尝试在QThread中调用get时,我没有收到任何结果,从不调用与响应关联的事件:

class RemoteControl : public QObject {
    Q_OBJECT
    QNetworkAccessManager* manager;

public:
    explicit RemoteControl(QObject* parent = 0); 
    ~RemoteControl() {}

public slots:
    void process() {
        std::cout << "start" << std::endl;

        while (true)    {
            execute();
            std::cout << "called" << std::endl;
            sleep(5);
        }
    }
    void execute() {
        QUrl url("my request for num of visitors that works..");
        QNetworkRequest req;
        req.setUrl(url);
        req.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
        QNetworkReply* reply = manager->get(req);
    }
    void downloadFinished(QNetworkReply* reply) {
        std::cout << "finished called" << std::endl;
        QByteArray resp = reply->readAll();
        std::cout << resp.data() << std::endl;
    }

signals:
    void finished();

    private:
    WebRequest* WebReq_;
};


RemoteControl::RemoteControl(bool* enable, LoggerHandle* Log, QObject* parent) : QObject(parent)
{
    enable_ = enable;
    Log_    = Log;
    running_ = false;
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this,
       SLOT(downloadFinished(QNetworkReply*)));
}

int main() {
    //.... my code....

    QThread* t3 = new QThread;
    RemoteContr->moveToThread(t3);
    QObject::connect(t3, SIGNAL(started()), RemoteContr, SLOT(process()));
    t3->start();

    //.... my code....
}

所以,会发生的是使用此代码我没有收到任何错误,在输出中我可以看到startcalled但从不finished called。 似乎永远不会调用事件downloadFinished

你可以帮我理解为什么吗? 我的班级RemoteControl出了什么问题?

由于 安德烈

1 个答案:

答案 0 :(得分:1)

您不需要线程。 QNetworkAccessManager是异步的,因此您正在使用的调用不会阻塞。而不是一个线程,只需在主函数中执行以下操作:

QTimer * timer = new QTimer; 
connect(timer, SIGNAL(timeout()), RemoteContr, SLOT(execute());
timer->start(5000);  // = 5 seconds

然后,每5秒调用execute,这似乎就是你想要的。

顺便说一下,我认为你没有得到结果的原因是while中的process循环阻塞了线程。您可以使用此方法摆脱process位置。