Cross-thread signal slot, how to send char * - c++

I've created a simple Qt GUI App and I've created a simple thread in it using worker and worker thread (see below codes, it is a simple code which will be used in a large program).
In this program when I push the push button, the thread is created and started and then I send to the thread a char * containing a file name to be read. But when I send for example the string "salam", it shows me extra characters and file cannot be opened( in console):
"filename=salam▬»
ìax↔↑♂"
Why does this occur?
MainWindow.cpp:
void MainWindow::on_pushButton_clicked()
{
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(&workerThread,SIGNAL(finished()),
worker, SLOT(deleteLater()));
connect(this, SIGNAL(operate(char *,int)),
worker, SLOT(doWork(char *,int)));
workerThread.start();
char *name=new char[5];
name[0]='s';name[1]='a';name[2]='l';name[3]='a';name[4]='m';
emit operate(name,5);
//vec=new QVector<double>();
}
worker.cpp:
void Worker::doWork(char *fileName,int size){
cout<<"filename="<<fileName<<endl;
}
worker.h:
class Worker : public QObject
{
Q_OBJECT
QThread workerThread;
public :
Worker();
public slots:
void doWork(char *fileName,int size) ;
};
#endif // WORKER_H
(Don't forget to add CONFIG+= console in .pro file if you want to test it.)

The problem you have is completely unrelated to Qt, signals or multiple threads.
The char* you're creating isn't null-terminated, so you cannot use it with functions (or operators) that expect char*s to be C strings - they rely on the null terminator. What you're seeing on your console is the result of that - the operator<< overload for char* will print out characters until a zero is encountered. You're printing whatever garbage values are stored in memory after your 5 characters (this is undefined behavior btw).
If you want to stick with char* for whatever reason, and expect to use it with functions that require C-style strings, you must zero-terminate it. (And take care of freeing it, that's not going to happen automatically.)

Related

QLabel not updating image content [duplicate]

I work in Qt and when I press the button GO I need to continuously send packages to the network and modify the interface with the information I receive.
The problem is that I have a while(1) in the button so the button never finishes so the interface is never updated. I thought to create a thread in the button and put the while(){} code there.
My question is how can I modify the interface from the thread? (For example how can I modify a textBox from the thread ?
Important thing about Qt is that you must work with Qt GUI only from GUI thread, that is main thread.
That's why the proper way to do this is to notify main thread from worker, and the code in main thread will actually update text box, progress bar or something else.
The best way to do this, I think, is use QThread instead of posix thread, and use Qt signals for communicating between threads. This will be your worker, a replacer of thread_func:
class WorkerThread : public QThread {
void run() {
while(1) {
// ... hard work
// Now want to notify main thread:
emit progressChanged("Some info");
}
}
// Define signal:
signals:
void progressChanged(QString info);
};
In your widget, define a slot with same prototype as signal in .h:
class MyWidget : public QWidget {
// Your gui code
// Define slot:
public slots:
void onProgressChanged(QString info);
};
In .cpp implement this function:
void MyWidget::onProgressChanged(QString info) {
// Processing code
textBox->setText("Latest info: " + info);
}
Now in that place where you want to spawn a thread (on button click):
void MyWidget::startWorkInAThread() {
// Create an instance of your woker
WorkerThread *workerThread = new WorkerThread;
// Connect our signal and slot
connect(workerThread, SIGNAL(progressChanged(QString)),
SLOT(onProgressChanged(QString)));
// Setup callback for cleanup when it finishes
connect(workerThread, SIGNAL(finished()),
workerThread, SLOT(deleteLater()));
// Run, Forest, run!
workerThread->start(); // This invokes WorkerThread::run in a new thread
}
After you connect signal and slot, emiting slot with emit progressChanged(...) in worker thread will send message to main thread and main thread will call the slot that is connected to that signal, onProgressChanged here.
P.s. I haven't tested the code yet so feel free to suggest an edit if I'm wrong somewhere
So the mechanism is that you cannot modify widgets from inside of a thread otherwise the application will crash with errors like:
QObject::connect: Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
Segmentation fault
To get around this, you need to encapsulate the threaded work in a class, like:
class RunThread:public QThread{
Q_OBJECT
public:
void run();
signals:
void resultReady(QString Input);
};
Where run() contains all the work you want to do.
In your parent class you will have a calling function generating data and a QT widget updating function:
class DevTab:public QWidget{
public:
void ThreadedRunCommand();
void DisplayData(QString Input);
...
}
Then to call into the thread you'll connect some slots, this
void DevTab::ThreadedRunCommand(){
RunThread *workerThread = new RunThread();
connect(workerThread, &RunThread::resultReady, this, &DevTab::UpdateScreen);
connect(workerThread, &RunThread::finished, workerThread, &QObject::deleteLater);
workerThread->start();
}
The connection function takes 4 parameters, parameter 1 is cause class, parameter 2 is signal within that class. Parameter 3 is class of callback function, parameter 4 is callback function within the class.
Then you'd have a function in your child thread to generate data:
void RunThread::run(){
QString Output="Hello world";
while(1){
emit resultReady(Output);
sleep(5);
}
}
Then you'd have a callback in your parent function to update the widget:
void DevTab::UpdateScreen(QString Input){
DevTab::OutputLogs->append(Input);
}
Then when you run it, the widget in the parent will update each time the emit macro is called in the thread. If the connect functions are configured properly, it will automatically take the parameter emitted, and stash it into the input parameter of your callback function.
How this works:
We initialise the class
We setup the slots to handle what happens with the thread finishes and what to do with the "returned" aka emitted data because we can't return data from a thread in the usual way
we then we run the thread with a ->start() call (which is hard coded into QThread), and QT looks for the hard coded name .run() memberfunction in the class
Each time the emit resultReady macro is called in the child thread, it's stashed the QString data into some shared data area stuck in limbo between threads
QT detects that resultReady has triggered and it signals your function, UpdateScreen(QString ) to accept the QString emitted from run() as an actual function parameter in the parent thread.
This repeats every time the emit keyword is triggered.
Essentially the connect() functions are an interface between the child and parent threads so that data can travel back and forth.
Note: resultReady() does not need to be defined. Think of it as like a macro existing within QT internals.
you can use invokeMethod() or Signals and slots mechanism ,Basically there are lot of examples like how to emit a signal and how to receive that in a SLOT .But ,InvokeMethod seems interesting .
Below is example ,where it shows How to change the text of a label from a thread:
//file1.cpp
QObject *obj = NULL; //global
QLabel *label = new QLabel("test");
obj = label; //Keep this as global and assign this once in constructor.
Next in your WorkerThread you can do as below:
//file2.cpp (ie.,thread)
extern QObject *obj;
void workerThread::run()
{
for(int i = 0; i<10 ;i++
{
QMetaObject::invokeMethod(obj, "setText",
Q_ARG(QString,QString::number(i)));
}
emit finished();
}
you start thread passing some pointer to thread function (in posix the thread function have the signature void* (thread_func)(void*), something equal under windows too) - and you are completely free to send the pointer to your own data (struct or something) and use this from the thread function (casting pointer to proper type). well, memory management should be though out (so you neither leak memory nor use already freed memory from the thread), but this is a different issue

QT - Mainwindow doesn't update unless it's closed

I'm trying to update the main window by calling updateGUI function in a thread every 500 ms. The window is displayed but not updated with the new values unless I close the window. When I do so, a new window is opened with the new value. I found this question but it didn't answer my question. I knew that (as stated in qt documentation)
QApplication::exec enters the main event loop and waits until
exit() is called.
I tried to use processEvents() but the main window is opened and closed repeatedly and very fast that I can't even see it. Here is my code:
float distanceToObject;
bool objectDetected;
Modes currentMode;
void timerStart(std::function<void(void)> func, unsigned int interval)
{
std::thread([func, interval]()
{
while (true)
{
auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval);
func();
std::this_thread::sleep_until(x);
}
}).detach();
}
int updateGUI(void)
{
int argc = 0;
char **argv = NULL;
QApplication a(argc, argv);
MainWindow w;
// Set text of a label
w.setDistance(QString::number(distanceToObject));
// Also update objectDetected and currentMode values
w.show();
//a.processEvents();
return a.exec();
}
void sendMsg(void)
{
// Send heartbeat signal to another device
}
void receiveMsg(void)
{
// Read messages from the other device and update the variables
// These two values change continuously
objectDetected = true;
distanceToObject = 5.4;
}
void decide(void)
{
// The core function of the program. Takes relatively long time
// Run a decision-making algorithm which makes decisions based on the values received from the other device.
// Update some variables according to the made decisions
currentMode = Auto;
// Execute functions according to the made decisions.
setMode(currentMode);
}
int main(void)
{
timerStart(updateGUI, 500);
timerStart(sendMsg, 1000);
timerStart(receiveMsg, 10);
timerStart(decide, 500);
}
How can I update the main window with the variables' values correctly?
Your thread does not update the MainWindow, but it does create an entirely new QApplication and MainWindow on every iteration. Your thread should be stuck inside QApplication::exec until you quit the application (e.g. by closing the window). Only then should your thread's loop make further progress.
In general, you must be very careful when doing updates from outside the main thread, since typically GUI operations must be performed inside the main thread.
Think about using QThread, which already comes with its own event loop, which you can use to notify/update your window using a respective slot.
Without further details about what you are actually trying to achieve, it is not possible to give you further direction. I, at least, recommend that you create your QApplication and MainWindow inside the main thread (e.g. main). Then it depends what you are trying to 'update'. If you need to progress some data, then you can do that within your second thread and send the results to your MainWindow instance using signal-slot. If you need to draw onto the window, then this either has to be done in the main thread directly, or you might find a way to render into a separate buffer (i.e. QImage) from within your thread and then send this buffer to the main thread for drawing it into the window.
I try to sketch how something like this can be done. Notice, however, that this it neither complete nor compilable, but merely an outline.
First, you have your MainWindow and add to it a signal, that notifies all observers to start doing their work (will become clear in a moment). Furthermore, you add slots that will be invoked whenever one of your values changes. Those slots run in the main thread (and are members of the MainWindow) and thus can update the window however they need to:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
// constructors and stuff
void startWorking()
{
emit startWorkers();
}
public slots:
void onModeChanged(Modes m)
{
// update your window with new mode
}
void onDistanceChanged(float distance)
{
// update your window with new distance
}
signals:
void startWorkers();
};
Next, you build a Worker class, that encapsulates all the 'background work' you like to do (basically what your thread did in your original code):
class Worker : public QObject
{
Q_OBJECT
public:
// constructors and stuff
public slots:
void doWork()
{
while(!done)
{
// do stuff ...
Modes m = // change mode
emit modeModified(m);
// do stuff ...
float distance = // compute distance
emit distanceModified(distance);
// do stuff ...
}
}
signals:
void modeModified(Modes m);
void distanceModified(float distance);
};
Note, that Worker must inherit QObject and that your doWork method must be a public slot. Furthermore, you add a signal for each of the values you like your MainWindow to be informed about. No implementation for them is needed, since it is generated by the Qt MOC (Meta Object Compiler). Whenever one of the respective values changes, simply emit the corresponding signal and pass the new value.
Lastly, you put everything together:
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow window;
// create a worker object
Worker* worker = new Worker;
// connect signals and slots between worker and main window
QObject::connect(worker, &Worker::modeModified,
&window, &MainWindow::onModeChanged);
QObject::connect(worker, &Worker::distanceModified,
&window, &MainWindow::onDistanceChanged);
QObject::connect(&window, &MainWindow::startWorkers,
worker, &Worker::doWork);
// create a new thread
QThread* thread = new QThread;
// send worker to work inside this new thread
worker->moveToThread(thread);
thread->start();
// show window and start doing work
window.show();
window.startWorking();
// start main loop
int result = app.exec();
// join worker thread and perform cleanup
return result;
}
Alright, let's go through it. First, you create your QApplication and MainWindow inside your main thread. Next, create an instance of your Worker object (could create multiple here). Then you connect the signals of the worker to the slots of the window and vice versa. Once these connections are established, whenever you emit a signal, the connected slot is invoked by Qt (and passed values are transmitted). Notice, that this connection works across thread boundaries. Whenever a signal is emitted from a thread different then the receiving object's thread, Qt will send a message, which is processed in the receiving object's thread.
Then you tell Qt that you want your worker to live inside another thread using QObject::moveToThread. See here for a very detailed explanation of how to correctly use QThread and objects inside it.
The rest is then simple. show your window and start processing. Here different ways are possible. I just call the startWorking method here, which then emits the startWorkers signal, which is connect to the worker's doWork method, such that doWork will start executing after this signal is received by the other thread.
You then call QApplication::exec which runs the main thread's event loop, where all these signals are processed by Qt. Once your application is closed (e.g. by calling quit or closing the main window) the exec method returns and you are back in main. Notice, that you need to correctly close the thread (e.g. by sending an addition signal that stops the while loop) and join it. You also should delete all the allocated objects (worker, thread). I omitted this here for simplicity of the code example.
Answering your Question
I have many functions, e.g., updateClips and mavReceive that should be called periodically and run independently from each other. I should create a different Worker class for each function, as each has different signals, and a QThread object for each of these functions, right? I don't need startTimer() anymore? If yes, how can I control the calling interval for each function (used to be done in startTimer()
from the comment:
The answer greatly depends on what exactly you mean by "should be called periodically". Who is supposed to call them? The user? Or should they just be executed periodically?
So in principle, you can have multiple workers in one thread. However, if they are supposed to do work all the time (spin in a while loop) it does not make sense, since one is running and all others are blocked. In that case you would have one thread for each worker.
If I understand you correctly, you are interested in updating something periodically (e.g. every 500ms). In that case I highly recommend using the QTimer. You can set an interval and then start it. The timer will then periodically emit the timeout signal, which you can connect to whatever function (more precisely slot) you want to have executed.
An updated version of the Worker could look like this:
class Worker : public QObject
{
Q_OBJECT
public:
Worker()
{
QObject::connect(&modeTimer_, &QTimer::timeout,
this, &Worker::onModeTimerTimeout);
QObject::connect(&distanceTimer_, &QTimer::timeout,
this, &Worker::onDistanceTimerTimeout);
modeTimer_.start(500); // emit timeout() every 500ms
distanceTimer_.start(100); // emit timeout() every 100ms
}
public slots:
void onModeTimerTimeout()
{
// recompute mode
Modes m = // ...
emit modeModified(m);
}
void onDistanceTimerTimeout()
{
// recompute distance
float distance = // ...
emit distanceModified(distance);
}
signals:
void modeModified(Modes m);
void distanceModified(float distance);
private:
QTimer modeTimer_;
QTimer distanceTimer_;
};
Notice, the connections established in the constructor. Whenever one of the timers times out, the connected slot is invoked. This slot then may compute whatever it needs to and afterwards send the result back to the MainWindow in the main thread using the same signal as before.
So, as you see, you can have multiple timers / re-computations / update signals within one Worker (and thus, one thread). However, the crucial point for an implementation is, how long the computations take. If they take very long (e.g. nearly as long as the intervals) then you should think about using multiple threads to speed up the computation (meaning: perform one computation in each thread). As I slowly seem to get a clearer picture of what you want to achieve, I am wondering whether it is only about these periodic updates that you 'misused' the thread for in your question. If this is indeed the case, then you do not need that thread and Worker at all. Then simply add the timers to your MainWindow and connect their timeout signal to the respective slot of the MainWindow directly.

Issues with Qt's signals and slots behavior with multithreading

I'm currently trying to understand how signals and slots in Qt behave with threads.
I've tried to run a small test with the following code:
class Worker : public QObject{
Q_OBJECT
public:
Worker(int _value){value = _value;}
~Worker(){};
int value;
public slots:
void changeValue(int newValue){value = newValue;}
void doWork(){
while(1){
_sleep(500);
std::cout << "Value is " << value << std::endl;
if(value == 0)break;
}
emit finished();
}
signals:
void finished();
};
class Manager : public QObject{
Q_OBJECT
public:
Manager(){}
~Manager(){};
signals:
void modifiedValue(int value);
public:
void changeTheValue(int value){emit modifiedValue(value);}
};
Basically, the worker display its value member every once in a while, and has a slot with a function that modifies the value.
The manager has the only purpose of emitting a signal with a new value when changeTheValue is called, that maps to the slot in Worker that modifies the value member.
Then I make my Worker class work in a thread the following way :
QThread myThread;
Worker myWorker(10);
Manager manager;
myWorker.moveToThread(&myThread);
QObject::connect(&myThread, SIGNAL(started()), &myWorker,SLOT(doWork()));
QObject::connect(&myWorker, SIGNAL(finished()), &myThread, SLOT(quit()));
QObject::connect(&myWorker, SIGNAL(finished()), &myWorker, SLOT(deleteLater()));
QObject::connect(&myThread, SIGNAL(finished()), &myThread, SLOT(deleteLater()));
QObject::connect(&manager, SIGNAL(modifiedValue(int)),
&myWorker, SLOT(changeValue(int)));
myThread.start();
for(int i = 1; i < 10 ; i++){
_sleep(1000);
manager.changeTheValue(i);
}
manager.changeTheValue(0);
But nothing happens. The value doesn't seem to be changed: output show a dozen lines with Value is 10.
What I can't understand is, why does the signal/slot mapping with Manager::modifiedValue and Worker::changeValue does not seem to work ? Is it only because the thread is currently running the doWork()'s loop ? Where does the call to the slots ends up then (queued, discarded, other) ?
I couldn't find much more on how does the signals/slots mechanism work with threads (I only found this thread which explains in which thread's call stack does the call to the slot end up, but the link provided in the answer seems outdated and leads to Qt 5 home).
To sum up the questions:
Why does the call to the slot that modifies the value does nothing ?
Is it possible to make this work (adding thread-safety wherever necessary) and how ?
There are multiple modes of how signals and slots work with threads (you absolutely must use QThreads for these to work!). These are documented in the manual:
http://qt-project.org/doc/qt-4.8/threads-qobject.html#signals-and-slots-across-threads
The mistake in your code is that the Qt event loop is never called (as doWork never returns). For a repeating call you should be using a timer in that thread. Alternatively (NOT the recommended solution) you can call processEvents in your infinite loop.

return an unsigned char in a signal/slot mechanism in Qt

I'm using QThreads in Qt, and I'm creating a signal in the worker so it can return an unsigned char buf[10] to be plotted in the gui thread. here's my signal.
unsigned char Worker::newinfo(unsigned char buf[10])
{
return buf;
}
what's wrong here?
in my function where the buf is received I emit the signal so it can be caught in the gui slot:
emit newinfo(buf);
connect(worker, SIGNAL(newinfo(unsigned char[])), this, SLOT(process_new_info(unsigned char[])));
it tels me there is amultiple defenition of newinfo().
here's my worker class:
class Worker : public QObject
{
Q_OBJECT
public:
Worker(FILE *datafile, int sockint, int bitsint);
~Worker();
FILE *data;
int sock;
int bits;
public slots:
void doWork();
signals:
void finished();
unsigned char newinfo(unsigned char buf[10]);
private:
};
That doesn't make sense at all. And your problem will go away if you change to std::vector<unsigned char> or a QByteArray.
moc_gui.cpp:110: multiple definition of Worker::newinfo(unsigned char*)' gui.cpp:64: first defined here
Signal are not meant to be defined explicitly by the programmer, but by the moc. And when you define signals or slots, they need to be void.
It seems what you want to do can be achieved with a combination of QtConcurrent::run() (for asynchronous execution) and a QFutureWatcher (for asynchronous access to the result ). Look it up on SO, there are plenty of posts.
EDIT:
First of all return buf[10]; in the code above return the 11th element of buf which doesnt make sense as you said you have 10 elements. Second, assuming everything else is correct, transmitting a pointer in a signal is sources of defects. Either both threads may access concurrently to the same data, or the GUI may try to access the data buffer while it is not valid. And as ypnos, you can avert this particular issue by passing objects which can be safely transmitted between threads.

QObject: Cannot create children for a parent that is in a different thread

EDIT:
I tried doing what you guys told me in comments ... :
Citizen * c = new Citizen(this);
QThread thread;
c->moveToThread(&thread);
connect(&thread, SIGNAL(started()), c, SLOT(ProcessActions()));
thread.start();
This produces even more errors:
QThread: Destroyed while thread is still running
ASSERT failure in QThread::setTerminationEnabled(): "Current thread was not started with QThread.", file c:\ndk_buildrepos\qt-desktop\src\corelib\thread\qthread_win.cpp, line 542
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
QObject::killTimers: timers cannot be stopped from another thread
I am having problems with this error ... I'm stuck on this for 2 days already and can't get a solution.
Header:
class Citizen : public QThread
{
Q_OBJECT
QNetworkAccessManager * manager;
private slots:
void onReplyFinished(QNetworkReply* net_reply);
public:
Citizen(QObject * parent);
void run();
};
Implementation:
Citizen::Citizen(QObject * parent)
{
manager = new QNetworkAccessManager;
connect(_net_acc_mgr, SIGNAL(finished(QNetworkReply*)),
this, SLOT(onReplyFinished(QNetworkReply*)));
}
void Citizen::onReplyFinished(QNetworkReply* net_reply)
{
emit onFinished(net_reply);
}
void Citizen::run()
{
manager->get(QNetworkRequest(QUrl("http://google.com"));
QEventLoop eLoop;
connect(manager, SIGNAL( finished( QNetworkReply * ) ), &eLoop, SLOT(quit()));
eLoop.exec(QEventLoop::ExcludeUserInputEvents);
qDebug() << "loaded google!";
exec();
}
When manager->get() gets executed, I get the following error:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNetworkAccessManager(0xc996cf8), parent's thread is QThread(0xaba48d8), current thread is Citizen(0xca7ae08)
When eLoop.exec() gets executed:
QObject::startTimer: timers cannot be started from another thread
I start this thread in the following manner:
Citizen * c = new Citizen(this);
c->start();
Why does this happen? How to solve this?
QObject: Cannot create children for a parent that is in a different thread.
You get this because you are creating the QNetworkAccessmanager in the constructor of Citizen, which is being called in the "original" thread. When the Citizen object is moved to the new thread the QNetworkAccessmanager still has its thread affinity set to the original thread but in the run call it will attempt to create the QNetworkReply object ( and probably other objects aswell ) in the new thread. Which produces the warning above.
If you create the manager in the run slot(or at any point after the Citizen object is moved to the new thread) that will not happen.
However you still have some issues. For instance, the Citizen class really doesn't need to be a QThread. It needlessly complicates it. It will suffice for your purpose(afaict) to subclass a QObject. Just make a normal slot and connect that to the QThread::started() signal. And as OrcunC pointed out you need to make sure that the QThread instance is properly scoped.
For more on threading: http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/
Example:
QThread *thread = new QThread;
thread->start();
Citizen *worker = new Citizen;
worker->moveToThread(thread);
//startWorking can be equivalent of the run function
//in your current implementation and this is where you should
//create the QNetworkAccessManager
QMetaObject::invokeMethod(worker,"startWorking");
I will just try to answer why you are seeing QThread: Destroyed while thread is still running error.
If you do this
void mtMethod () {
Citizen * c = new Citizen(this);
QThread thread;
c->moveToThread(&thread);
connect(&thread, SIGNAL(started()), c, SLOT(ProcessActions()));
thread.start();
}
The thread object will be destroyed when you exit the function but the thread that has been started is still running !. Qt is warning you that you should either stop the thread or create the thread object in a bigger scope. (i.e make it a member function of your class). Something like this :
class myClass
{
virtual ~myClass ();
QThread mythread;
};
myClass::~myClass
{
mythread.stop ();
}
void myClass::mtMethod () {
Citizen * c = new Citizen(this);
c->moveToThread(&mythread);
connect(&mythread, SIGNAL(started()), c, SLOT(ProcessActions()));
mythread.start();
}
I don't believe the new thread exists until run is called. So the constructor is a different thread than run(). What happens if you move the creation of the manager object from the constructor to run()? I imagine that will fix the first error, if not the timer error as well.
Also, I think many people are still building threads the way you are, but you might want to check out this.
You need to consider thread affinity. That error message is not lying or insane, it's telling you exactly what's wrong.
Your problems are mostly due to trying to subclass QThread. Even though the documentation recommends it, it is not the best way to use QThread. Please see this question and answer for more information and links.
I haven't figured out the startTimers error although it could be related to the first one. In any case, you should be able to fix the first error. I have run into this problem in Qt a few times and I find this to be the "best" way to work around it is to create an initialize function and a cleanUp function. All members of the class are pointers that are initialized to NULL until run is called. Note that "best" is in quotes because there are sure to be differing opinions but it works for most situations for me.
Header
class Citizen : public QThread {
Q_OBJECT
QNetworkAccessManager * manager;
private slots:
void onReplyFinished(QNetworkReply* net_reply);
public:
Citizen(QObject * parent);
void run();
private:
void initialize();
void cleanUp();
};
Implementation
Citizen::Citizen(QObject * parent) :
manager(NULL) {
}
void Citizen::onReplyFinished(QNetworkReply* net_reply) {
emit onFinished(net_reply);
}
void Citizen::run() {
initialize();
manager->get(QNetworkRequest(QUrl("http://google.com"));
QEventLoop eLoop;
connect(manager, SIGNAL( finished( QNetworkReply * ) ),
&eLoop, SLOT(quit()));
eLoop.exec(QEventLoop::ExcludeUserInputEvents);
qDebug() << "loaded google!";
exec();
cleanUp();
}
void Citizen::initialize() {
manager = new QNetworkAccessManager;
connect(_net_acc_mgr, SIGNAL(finished(QNetworkReply*)),
this, SLOT(onReplyFinished(QNetworkReply*)));
}
void Citizen::cleanUp() {
delete manager;
disconnect(_net_acc_mgr, SIGNAL(finished(QNetworkReply*)),
this, SLOT(onReplyFinished(QNetworkReply*)));
}