#ifndef MYTHREAD_H#define MYTHREAD_H#include <QThread>#include <QNetworkAccessManager>#include <QNetworkReply>#include <QTimer>#include <QNetworkConfigurationManager>#include <Parser>#include <Serializer>#include <QObjectHelper>#include <QTime>#include "macroconfig.h"class MyThread : public QThread{ Q_OBJECTpublic: enum Status{ PointsPay, FullInfo }; explicit MyThread(QObject *parent = 0); void getPointsPay(int); QString getPlatform() ; void setServerTime(QString);protected: void run();private: QString m_skey; QNetworkAccessManager *m_manager; QNetworkReply *m_reply; QNetworkConfigurationManager m_config; Status m_flag; QTimer m_timer; QTimer m_TimerWating; QTime m_lastTimeInfo; QTime m_lastTimePay; QString m_serverTime; QString m_os; QMap<int,QVariantMap> m_pointsPay; signals: QVariantMap succes(QVariantMap); QMap<int,QVariantMap> succes(QMap<int,QVariantMap>); QString Error(QString); public slots: void getFullInfo(); void finish(QNetworkReply*); void Error(QNetworkReply::NetworkError); void isOnlain(); void setParamAndStart(QString skey); };#endif // MYTHREAD_H
#include "mythread.h"#include <QDebug>MyThread::MyThread(QObject *parent) : QThread(parent){ //moveToThread(this); если раскоментировать то функция run вообще не вызывается.... m_manager = new QNetworkAccessManager(); m_manager->moveToThread(this); connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(finish(QNetworkReply*))); connect(&m_TimerWating,SIGNAL(timeout()),this,SLOT(isOnlain())); m_lastTimeInfo.addSecs(-60); m_lastTimePay.addSecs(-60); m_os = this->getPlatform(); m_timer.setInterval(60000);}void MyThread::setParamAndStart(QString skey){ // устанавливаем ключ и запускаем поток if (!skey.isEmpty()) { m_skey = skey; start(); // запускаем поток. Пробовала и из main.cpp но ничего не изменилось }}void MyThread::run(){ qDebug()<<"run"; getPointsPay(1); //getFullInfo(); m_timer.start(); exec(); // использовать собственную очередь событий}void MyThread::getPointsPay(int type){ // поработать с объектом QTime qDebug()<<__FUNCTION__<<type; m_flag = PointsPay; //if (m_lastTimePay.addSecs(30) <= QTime::currentTime()){ QString Responce = "/?r=client/paymentplacesinfo&place_type_id=%1"; Responce = HOST + Responce.arg(QString::number(type)); if (m_config.isOnline()){ m_lastTimePay = QTime::currentTime(); m_reply = m_manager->get(QNetworkRequest(Responce)); m_reply->moveToThread(this); m_reply->ignoreSslErrors(); connect(m_reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(Error(QNetworkReply::NetworkError))); } else m_TimerWating.start(30000); // }}void MyThread::getFullInfo(){ m_flag = FullInfo; if (m_lastTimePay.addSecs(30) <= QTime::currentTime()){ // проверяем как давно мы запрашивали эту информацию QString param = "/?r=client/getfullInfo&skey=%1&platform=%2&date=%3"; param = HOST+param.arg(m_skey,m_os,m_serverTime); if (m_config.isOnline()){ m_lastTimeInfo = QTime::currentTime(); m_reply = m_manager->get(QNetworkRequest(param)); connect(m_reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(Error(QNetworkReply::NetworkError))); m_reply->ignoreSslErrors(); } else m_TimerWating.start(30000); }}void MyThread::finish(QNetworkReply* reply){ QByteArray json = reply->readAll(); QJson::Parser parser; bool ok; QVariantMap buffer = parser.parse (json, &ok).toMap(); if (ok){ if (m_flag == PointsPay){ m_pointsPay[buffer["current"].toInt()] = buffer; if (buffer["current"].toInt()!=3) this->getPointsPay(buffer["current"].toInt()+1); // запрашиваем следующую точку оплаты else this->getFullInfo(); // получаем пользовательскую информацию } else { emit succes(buffer); // возвращаем пользовательскую информацию QVariantMap news = buffer["news"].toMap(); QList<QVariant> created = news.value("created").toList(); QList<QVariant> modified = news.value("modified").toList(); QList<QVariant> deleted = news.value("deleted").toList(); if (created.isEmpty() || modified.isEmpty() || deleted.isEmpty()){ this->getPointsPay(1); } m_timer.start(); } }}void MyThread::Error(QNetworkReply::NetworkError error){ switch(error) { case QNetworkReply::ConnectionRefusedError:{ emit Error(QString::fromLocal8Bit("Сервер перегружен.")); break; } case QNetworkReply::ContentNotFoundError:{ emit Error(QString::fromLocal8Bit("Ошибка сервера 404.")); break; } case QNetworkReply::HostNotFoundError:{ emit Error( QString::fromLocal8Bit("Не найден удаленный сервер.")); break; } default: { emit Error(m_reply->errorString()); break; } } m_TimerWating.start(60000); // спустя минуту попытаемся вновь соедениться с сервером}void MyThread::isOnlain(){ if (m_config.isOnline()){ m_TimerWating.stop(); if (m_flag == PointsPay) this->getPointsPay(m_pointsPay.count()); else this->getFullInfo(); }}void MyThread::setServerTime(QString time){ this->m_serverTime = time;}QString MyThread::getPlatform() {#if defined(Q_OS_WIN) return "winxp";#elif defined(Q_OS_LINUX) return "linux";#elif defined(Q_OS_MACOSX) return "macos";#endif}
class MyClass : public QObject{ Q_OBJECTsignals: //Сигнал о завершении работы "void process()" void finished();public: //Обращаем внимание, что в конструкторе не указываем родителя, //но при этом можем внести какие-либо другие параметры. MyClass() : QObject() {} virtual ~MyClass() {}public slots: void process() { //Здесь наш код, который должен выполниться в отдельном потоке. ... //Отсылаем сигнал о завершении выполнения. emit finished(); }private: //Здесь указываем наши приватные объекты и переменные.};
QThread *thread = new QThread;MyClass *myclass = new MyClass();myclass->moveToThread(thread);connect(thread, SIGNAL(started()), myclass, SLOT(process()));connect(myclass, SIGNAL(finished()), thread, SLOT(quit()));connect(myclass, SIGNAL(finished()), myclass, SLOT(deleteLater()));connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));thread->start();
C++ (Qt) m_manager = new QNetworkAccessManager();
QThread *thread = new QThread(this); //Сам QThread может иметь parent'аthread->start();...MyClass *myclass = new MyClass();myclass->moveToThread(thread);connect(this, SIGNAL(my_signal()), myclass, SLOT(process()));connect(myclass, SIGNAL(finished()), this, SLOT(my_slot()));
void MyClass::process() { //Здесь наш код, который должен выполниться в отдельном потоке. ... //Перемещаем объект обратно в главный поток. moveToThread(QCoreApplication::instance()->thread()); //Отсылаем сигнал о завершении выполнения. emit finished();}