PDA

View Full Version : pthread instead QThread



brevleq
22nd December 2008, 16:54
I need to develop three programs, and they should use some pthreads, I can't use QThread cause theacher said to use native threads.
The first program is a PLC simulator with:

10 analogic in;
10 analogic out;
10 digital in;
10 digital out;

I think I can use a pthread to create the "in" random values, but when I call the method to set the new values in QSpinBox, the frontend freezes!!
Using cout, I see that the values are been generated, and some X errors messages are shown, some have this: "(RENDER)". I think is just a render problem, but I don't know what can solve it!
Unfortunately, I don't have the source in these computer I'm using. I'll post som sources later, but someone have an ideia of what is happening??

jpn
22nd December 2008, 16:59
You must not touch the GUI in a worker thread.

brevleq
22nd December 2008, 17:08
????????

I didn't understand.:confused:

jpn
22nd December 2008, 17:17
From what I understood you call some spinbox method directly from a worker thread. This is not acceptable.

From Qt docs:

Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread. As noted earlier, QCoreApplication::exec() must also be called from that thread.

spirit
22nd December 2008, 17:19
In practice, the impossibility of using GUI classes in other threads than the main thread can easily be worked around by putting time-consuming operations in a separate worker thread and displaying the results on screen in the main thread when the worker thread is finished. This is the approach used for implementing the Mandelbrot and the Blocking Fortune Client example.

I suggest you carefully read Thread support in Qt (http://doc.trolltech.com/4.4/threads.html)

brevleq
22nd December 2008, 17:31
Ok I understood.

I should use mutex, semaphore or something to make main thread set the values right?

spirit
22nd December 2008, 17:34
yes, you can't call GUI methods in another thread. use signals/slots or custom event for communication between main and worker thread.

brevleq
23rd December 2008, 00:31
Ok

I've implemented custom signal/slots:


#ifndef PORTA_H
#define PORTA_H

#include <QObject>

class Porta : public QObject{

public:
static const int DISCRETE=0;
static const int BINARY=1;

Porta ();
int getValue ();
virtual void setType (int t);

protected:
int value;
pthread_t thread;
int type;

int createThread ();
static void *startThread (void *obj);
virtual void threadFunction(void)=0;

signals:
void valueChanged();

};

#endif


#include "PortaEntrada.h"

#include <iostream>

using namespace std;

PortaEntrada::PortaEntrada(){
oscilation=BINARY;
}

void PortaEntrada::threadFunction(void){
while(1){
doGenerate();
sleep(5);
}
}

int PortaEntrada::doGenerate(){
value=generator->generate();
emit valueChanged();
}

void PortaEntrada::setOscilation (int o){
oscilation=(o%4)+1;
if(type==BINARY && oscilation!=BINARY){
oscilation=BINARY;
}
switch(oscilation){
case BINARY : generator=new (BGenerator);
break;
case QUADRATIC : generator=new (QGenerator);
break;
case TRIANGULAR : generator=new (TGenerator);
break;
case CONSTANT : generator=new (CGenerator);
break;
}
createThread();
}



#include "SpinView.h"
#include <iostream>

using namespace std;

SpinView::SpinView(QWidget *parent):QSpinBox(parent){
}


void SpinView::setModel(Porta *m){
View::setModel(m);
connect(m,SIGNAL(valueChanged()),this,SLOT(setInVi ew()));
}

void SpinView::setInValue(void){
setValue(model->getValue());
}


but when I run the program:


Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dInSpin1')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aInSpin1')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dOutSpin1')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aOutSpin6')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dInSpin2')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aInSpin2')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dOutSpin2')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aOutSpin7')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dInSpin3')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aInSpin3')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dOutSpin3')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aOutSpin8')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dInSpin4')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aInSpin4')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dOutSpin4')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aOutSpin9')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dInSpin5')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aInSpin5')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dOutSpin5')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aOutSpin10')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dInSpin6')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aInSpin6')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dOutSpin6')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aOutSpin1')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dInSpin7')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aInSpin7')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dOutSpin7')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aOutSpin2')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dInSpin8')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aInSpin8')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dOutSpin8')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aOutSpin3')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dInSpin9')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aInSpin9')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dOutSpin9')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aOutSpin4')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dInSpin10')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aInSpin10')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'dOutSpin10')
Object::connect: No such signal QObject::valueChanged()
Object::connect: (receiver name: 'aOutSpin5')

How can I connect this custom signal with my custom slot??:crying:

jpn
23rd December 2008, 07:16
Class Porta is missing the required Q_OBJECT macro.

PS. Please do not double post! Thread closed.