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

QNetworkAccessManager get called in a QThread because cyclic

我需要周期性地调用网络请求,所以,最简单的方法当然是创建一个线程并调用我的请求,然后休眠。 问题是我写了我的代码,它基本上可以工作。当我尝试在 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

你能帮我理解为什么吗? 我的 class RemoteControl 有问题吗?

谢谢 安德里亚

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

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

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

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