high_flyer
12th March 2007, 22:26
Hi,
Qt4.2.2 on linux.
I have implemented a threaded communication scheme, but the slots of a non gui thread class are executed in the GUI thread.
I was hoping maybe some one here could point to my mistake.
Here is what I did in meta code, after the code a text explaining the behavior:
//Base socket thread class
class SocketThread : public QThread
{
Q_OBJECT
protected:
QTcpSocket *m_socket;
QString m_host;
quint32 m_port;
QMutex m_socketMutex;
QDataStream *m_dataStream;
public:
SocketThread(QString host,quint32 port,QObject *parent = 0);
~SocketThread();
const QDataStream & stream();
void run();
public slots:
virtual void readSocket();
};
void SocketThread::run()
{
if(!m_socket)
{
m_socket = new QTcpSocket();
if(m_socket) m_dataStream = new QDataStream(m_socket);
connect(m_socket,SIGNAL(readyRead()),this,SLOT(rea dSocket()));
if(m_socket) m_socket->connectToHost(m_host,m_port);
}
exec();
}
//Actual working class
class HPSCSocket : public SocketThread
{
Q_OBJECT
public:
HPSCSocket(QString host,quint32 port,QObject *parent = 0);
~HPSCSocket();
signals:
void sig_hpscReadout(int,float,float);
public slots:
void sendHPSCCommand(HPSC_Command cmd,long usWait);
void readSocket();
};
void HPSCSocket::sendHPSCCommand(HPSC_Command cmd,long usWait=0)
{
qDebug()<<"HPSCSocket::sendHPSCCommand";
if(m_dataStream)
{
qDebug()<<"sending command";
*m_dataStream<<cmd;
m_socket->flush();
qDebug()<<"about to sleep "<<usWait;
usleep(usWait);
qDebug()<<"woke up";
}
}
//the class (GUI) that communicates through the threaded socket class HPSCSocket
FrmPower::FrmPower(BUS bus1,BUS bus2,QWidget *parent)
: QWidget(parent)
{
m_hpscSocket = new HPSCSocket(m_hpscHost.toString(),m_hpscPort,this);
connect(this,SIGNAL(sig_hpscCommand(HPSC_Command,l ong)),m_hpscSocket,SLOT(sendHPSCCommand(HPSC_Comma nd,long)),Qt::QueuedConnection);
connect(m_hpscSocket,SIGNAL(sig_hpscReadout(int,fl oat,float)),this,SLOT(hpscReadout(int,float,float) ));
}
void FrmPower::bus1()
{
command.cmd = SETCURR1;
command.var = m_src1a;
emit sig_hpscCommand(command,120000);
}
As you can see, a socket is created in its own thread (not the GUI thead) in SocketThread::run().
The GUI class FrmPower has a member variable of type HPSCSocket which is a subclass of the SocketThread class.
The aim of this scheme, is to allow FrmPower to send information through the threaded socket as can be seen in FrmPower::bus1().
(The reason is, that after each socket transmition there is a need for various sleep intervals, which would freeze the GUI thread, and other problems as well)
The problem is, that although the socket is created in seperate thread to the GUI thread, the execution of HPSCSocket::sendHPSCCommand() happens in the main GUI thread, and I have no idea why.
In addition, the output:
QSocketNotifier: socket notifiers cannot be enabled from another thread
comes out in HPSCSocket::sendHPSCCommand on the socket operations, but code runs, just not in the right thread.
If any one could point me to my mistake it will be very appreciated.
I didn't insert code that is not relevant for illustrating the problem, such as proper constructors , mutextes etc.
Thanks in advance!
Qt4.2.2 on linux.
I have implemented a threaded communication scheme, but the slots of a non gui thread class are executed in the GUI thread.
I was hoping maybe some one here could point to my mistake.
Here is what I did in meta code, after the code a text explaining the behavior:
//Base socket thread class
class SocketThread : public QThread
{
Q_OBJECT
protected:
QTcpSocket *m_socket;
QString m_host;
quint32 m_port;
QMutex m_socketMutex;
QDataStream *m_dataStream;
public:
SocketThread(QString host,quint32 port,QObject *parent = 0);
~SocketThread();
const QDataStream & stream();
void run();
public slots:
virtual void readSocket();
};
void SocketThread::run()
{
if(!m_socket)
{
m_socket = new QTcpSocket();
if(m_socket) m_dataStream = new QDataStream(m_socket);
connect(m_socket,SIGNAL(readyRead()),this,SLOT(rea dSocket()));
if(m_socket) m_socket->connectToHost(m_host,m_port);
}
exec();
}
//Actual working class
class HPSCSocket : public SocketThread
{
Q_OBJECT
public:
HPSCSocket(QString host,quint32 port,QObject *parent = 0);
~HPSCSocket();
signals:
void sig_hpscReadout(int,float,float);
public slots:
void sendHPSCCommand(HPSC_Command cmd,long usWait);
void readSocket();
};
void HPSCSocket::sendHPSCCommand(HPSC_Command cmd,long usWait=0)
{
qDebug()<<"HPSCSocket::sendHPSCCommand";
if(m_dataStream)
{
qDebug()<<"sending command";
*m_dataStream<<cmd;
m_socket->flush();
qDebug()<<"about to sleep "<<usWait;
usleep(usWait);
qDebug()<<"woke up";
}
}
//the class (GUI) that communicates through the threaded socket class HPSCSocket
FrmPower::FrmPower(BUS bus1,BUS bus2,QWidget *parent)
: QWidget(parent)
{
m_hpscSocket = new HPSCSocket(m_hpscHost.toString(),m_hpscPort,this);
connect(this,SIGNAL(sig_hpscCommand(HPSC_Command,l ong)),m_hpscSocket,SLOT(sendHPSCCommand(HPSC_Comma nd,long)),Qt::QueuedConnection);
connect(m_hpscSocket,SIGNAL(sig_hpscReadout(int,fl oat,float)),this,SLOT(hpscReadout(int,float,float) ));
}
void FrmPower::bus1()
{
command.cmd = SETCURR1;
command.var = m_src1a;
emit sig_hpscCommand(command,120000);
}
As you can see, a socket is created in its own thread (not the GUI thead) in SocketThread::run().
The GUI class FrmPower has a member variable of type HPSCSocket which is a subclass of the SocketThread class.
The aim of this scheme, is to allow FrmPower to send information through the threaded socket as can be seen in FrmPower::bus1().
(The reason is, that after each socket transmition there is a need for various sleep intervals, which would freeze the GUI thread, and other problems as well)
The problem is, that although the socket is created in seperate thread to the GUI thread, the execution of HPSCSocket::sendHPSCCommand() happens in the main GUI thread, and I have no idea why.
In addition, the output:
QSocketNotifier: socket notifiers cannot be enabled from another thread
comes out in HPSCSocket::sendHPSCCommand on the socket operations, but code runs, just not in the right thread.
If any one could point me to my mistake it will be very appreciated.
I didn't insert code that is not relevant for illustrating the problem, such as proper constructors , mutextes etc.
Thanks in advance!