Название: Проблема с QThread (run в основном потоке?)
Отправлено: alexcoder от Февраль 22, 2015, 01:55
Клепаю класс на основе потока (с возвращением результата произвольного типа обратно в основной поток). Судя по всему - код из run() срабатывает в потоке GUI, а не отдельном. Что делается неверно? #ifndef ASYNC_H #define ASYNC_H
#include <QThread> #include <functional>
/** * Async callback class */ template<typename T> class Async : public QThread { public: Async(std::function<T()> worker, std::function<void(T)> callback); private: T result; std::function<T()> func; std::function<void(T)> returner; protected: void run(); private: void onfinished(); };
/** * Run async call * @param worker Function, that will work in other thread and return some result * @param callback callback function */ template<typename T> Async<T>::Async(std::function<T()> worker, std::function<void(T)> callback) : QThread() { func = worker; returner = callback; connect(this, SIGNAL(finished()), this, SLOT(onfinished())); start(); }
template<typename T> void Async<T>::run() { result = func(); }
template<typename T> void Async<T>::onfinished() { returner(result); }
#endif // ASYNC_H
UPD. И тут я понял, что код - полный бред и нуждается в отправке в мусорку :-)
Название: Re: Проблема с QThread (run в основном потоке?)
Отправлено: alexcoder от Февраль 22, 2015, 03:54
В итоге вышел такой код (уверен, что есть что исправить, но таки оно работает) Async.h #ifndef ASYNC_H #define ASYNC_H
#include <QVector> #include <functional> #include <AsyncInfo.h> #include <AsyncThread.h>
template<typename T> class Async { public: Async(std::function<T()> worker, std::function<void(T)> callback); static void remove(AsyncThread<T>* thread); private: static QVector<AsyncThread<T>*> threads; };
template<typename T> QVector<AsyncThread<T>*> Async<T>::threads;
template<typename T> Async<T>::Async(std::function<T()> worker, std::function<void(T)> callback) { AsyncInfo<T> info; info.worker = worker; info.callback = [callback](T info, QThread* thread) { callback(info); remove( (AsyncThread<T>*)thread ); }; AsyncThread<T>* thread = new AsyncThread<T>(info); threads.append(thread); thread->work(); }
template<typename T> void Async<T>::remove(AsyncThread<T>* thread) { int index = threads.indexOf(thread); threads.removeAt(index); }
#endif // ASYNC_H
AsyncInfo.h #ifndef ASYNCINFO_H #define ASYNCINFO_H
#include <QThread>
template<typename T> struct AsyncInfo { std::function<T()> worker; std::function<void(T, QThread* thread)> callback; };
#endif // ASYNCINFO_H
AsyncThread.h #ifndef ASYNCTHREAD_H #define ASYNCTHREAD_H
#include <QThread> #include <AsyncInfo.h> #include <QApplication>
template<typename T> class AsyncThread : public QThread { public: AsyncThread(AsyncInfo<T> info); void run(); void work(); public slots: void onfinished(); private: AsyncInfo<T> thread_info; T result; };
template<typename T> AsyncThread<T>::AsyncThread(AsyncInfo<T> info) : QThread() { thread_info = info; }
template<typename T> void AsyncThread<T>::work() { start(); while(isRunning()) { QApplication::processEvents(); } onfinished(); }
template<typename T> void AsyncThread<T>::run() { result = thread_info.worker(); }
template<typename T> void AsyncThread<T>::onfinished() { thread_info.callback(result,this); }
#endif // ASYNCTHREAD_H
|