Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
834 views
in Technique[技术] by (71.8m points)

multithreading - QTimer can only be used with threads started with QThread

So I have an interesting problem....a program I am (trying) to write is crashing with this error:

QObject::startTimer: QTimer can only be used with threads started with QThread 

The thing that baffles me is my program is single threaded. The goal of the class in question is to send POST data to a php page I have on my server. As soon as it tries to send the POST, I get that message. Here is my code.

#ifndef TRANSMISSIONS_H
#define TRANSMISSIONS_H
#include "name_spawn.h"
#include <QNetworkReply>
#include <QObject>
#include <QNetworkConfigurationManager>

class Transmissions : public QObject
{
    Q_OBJECT
public:
    Transmissions();
    void Send(GeneratedData);
public slots:
    void serviceRequestFinished(QNetworkReply*);
signals:
    void configurationAdded(const QNetworkConfiguration);
    void configurationChanged(const QNetworkConfiguration);
    void configurationRemoved(const QNetworkConfiguration);
    void onlineStateChanged(bool);
    void updateCompleted();
};

#endif // TRANSMISSIONS_H

And

#include "transmissions.h"
#include "name_spawn.h"
#include <QHttp>
#include <QUrl>
#include <QString>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <iostream>
#include <QNetworkAccessManager>
#include <QNetworkConfigurationManager>
#include <QObject>

using namespace std;

Transmissions::Transmissions()
{
}

void Transmissions::Send(GeneratedData User)
{
    cerr<<"transmitting"<<endl;
    QUrl serviceUrl = QUrl("http://192.168.1.138/postTest.php");
    QByteArray postData;
    QString username="user="+User.Email()+"&";
    QString Passwd="password="+User.pass();
    postData.append(username);
    postData.append(Passwd);

    QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
    connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*)));
    networkManager->post(QNetworkRequest(serviceUrl), postData);
}

void Transmissions::serviceRequestFinished(QNetworkReply *reply)
{
    //this will do other things once post is working
    QString data = reply->readAll();
    cerr <<"Data is "<< data.toStdString()<<endl;

}

I think what I am trying to do is fairly simple, but it is frustrating me to no end trying to get it to work. I didn't see anything in the documentation about QNetworkAccessManager requiring threads. I admit I don't know Qt that well, so any help (or links to complete POST examples) would be very appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To use a QTimer you need to have an event loop. QNAM obviously uses a timer to periodically check for the network reply.

You need to start the application event loop with QCoreApplication::exec() and then call QNAM methods like post after that.

I think you can call post before exec but you may come across this bug.

Also, note that up to Qt 4.7 QNAM did not use threading but with 4.8 this is changing.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...