PDA

View Full Version : Qthread



dognzhe
13th May 2009, 09:42
class ClientThread : public QThread
{
Q_OBJECT

public:
ClientThread(QObject *parent,int descriptor);
~ClientThread();

private:
int descriptor;
void run();

private slots:
void onFinish();
void tcpError( QAbstractSocket::SocketError error );
void onStateChanged( QAbstractSocket::SocketState socketState);

};



#include "clientthread.h"

ClientThread::ClientThread(QObject *parent, int descriptor)
: QThread(parent)//, socket(this)
{
this->descriptor=descriptor;
qWarning("ClientThread::ClientThread() %d\n", QThread::currentThreadId());

connect(this,SIGNAL(finished()),this,SLOT(onFinish ()));

}

ClientThread::~ClientThread()
{

}

void ClientThread::run(){

QTcpSocket socket;

if( !socket.setSocketDescriptor( descriptor ) )
{
qDebug( "Socket error!" );
return;
}
connect(&socket,SIGNAL( stateChanged (QAbstractSocket::SocketState)),this,SLOT (onStateChanged(QAbstractSocket::SocketState)));
connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(tcpError(QAbstractSocket::SocketError)) );

QString add=socket.peerAddress().toString();
qWarning()<<add;

qWarning("ClientThread::run() %d\n", QThread::currentThreadId());
exec();// this will keep the thread running.
}

void ClientThread::onFinish(){
int a = 12;

}



void ClientThread::tcpError(QAbstractSocket::SocketErro r error){

if( error == QAbstractSocket::RemoteHostClosedError )
return;

}

void ClientThread::onStateChanged( QAbstractSocket::SocketState socketState){
qWarning("ClientThread::onStateChanged() %d\n", QThread::currentThreadId());
switch (socketState){
case QAbstractSocket::UnconnectedState:
qWarning()<<"UnconnectedState";
default:
qWarning()<<socketState;
}


}


this two lines are not working :

connect(&socket,SIGNAL( stateChanged (QAbstractSocket::SocketState)),this,SLOT (onStateChanged(QAbstractSocket::SocketState)));
connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(tcpError(QAbstractSocket::SocketError)) );

and show error:

"QObject::connect: Cannot queue arguments of type 'QAbstractSocket::SocketError'
(Make sure 'QAbstractSocket::SocketError' is registered using qRegisterMetaType(
).)
QObject::connect: Cannot queue arguments of type 'QAbstractSocket::SocketState'
(Make sure 'QAbstractSocket::SocketState' is registered using qRegisterMetaType(
).)"

can anyone tell me how to link the signals of QtcpSocket to the slot in side of qthread???

qt is fucked

dognzhe
13th May 2009, 09:48
by the way, there is no compile error. it is real time error, so the slot will never get triggtered.

does any one know what cause this fail?

wagmare
13th May 2009, 10:08
threads use queued connection ... use Q_DECLARE_METATYPE and qRegisterMetaType ..

with queued connection the parameter must be of types that are known to qt,s meta object system
because qt needs to copy argument to store them in an event behind scene ...
register "QAbstractSocket::SocketState"

dognzhe
14th May 2009, 02:30
threads use queued connection ... use Q_DECLARE_METATYPE and qRegisterMetaType ..

with queued connection the parameter must be of types that are known to qt,s meta object system
because qt needs to copy argument to store them in an event behind scene ...
register "QAbstractSocket::SocketState"

but QAbstractSocket::SocketState is know type, if i move this outside the thread, then it works good!!~~~

gotta be the other problems

wysota
14th May 2009, 02:33
gotta be the other problems

No, wagmare is right - you need to register the type with Qt's meta-data system and with QVariant to be able to use it as an argument for a signal that is emitted across threads.

wagmare
14th May 2009, 06:31
but QAbstractSocket::SocketState is know type, if i move this outside the thread, then it works good!!~~~



even for emitting SIGNAL with QString .. i have to register it ....

dognzhe
14th May 2009, 08:47
do you know why emit behave like this in the qthread? in the main very thing is fine!

wagmare
14th May 2009, 09:20
do you know why emit behave like this in the qthread? in the main very thing is fine!

i stated it clearly in my first reply ....

Qt supports three types of signal-slot connections:
http://doc.trolltech.com/4.2/threads.html#signals-and-slots-across-threads

here we are using queued connection
* with queued connections, the parameters must be of types that are known to qt's meta object system

* because Qt needs to copy the arguments to store them in an event behind the scene ..

if error came
" QObject ::connect:cannot queue arguments of type 'MyType' "

call qRegisterMetaType() to register the data type 'MyType' before you establish the connection ....