[Solved]Problem emiting a signal with and enum from a thread
-
wrote on 10 Aug 2011, 19:15 last edited by
I've been away from QT for a few years and can't remember how to emit a signal from a thread which takes an enum as a parameter.
I have test code below.the slot for the qreal emit is processed but the enum mytype one is not.
Any help or clues would be aprreciated
Thank you
Paul@#ifndef QTTHREADS_H
#define QTTHREADS_H#include <QtGui/QMainWindow>
#include <QThread>
#include "ui_qtthreads.h"enum myType
{
abc
,def
,ghi
};class MyThread : public QThread
{
Q_OBJECT
public:
MyThread(QWidget * parent);
QWidget * m_parent;
protected:
void run();
bool m_bExit;
myType m_myTypeVar;signals:
void sgn_To_MainThread(qreal rValue);
void sgn_To_MainThread(::myType l_myTypeVar);
};class QTThreads : public QMainWindow
{
Q_OBJECTpublic:
QTThreads(QWidget parent = 0, Qt::WFlags flags = 0);
~QTThreads();
MyThread m_myThread;
myType m_myTypeVar;private:
Ui::QTThreadsClass ui;
public slots:
void slt_From_Worker(qreal rValue);
void slt_From_Worker(::myType l_myTypeVar);
};#endif // QTTHREADS_H@
@#include "qtthreads.h"
#include <QDebug>QTThreads::QTThreads(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
, m_myTypeVar(abc)
{m_myThread = new MyThread(this);
ui.setupUi(this);connect(this, SIGNAL(sgn_To_WorkThread(qreal))
,m_myThread, SLOT(slt_From_Main(qreal)), Qt::QueuedConnection);
connect(this, SIGNAL(sgn_To_WorkThread(::myType))
,m_myThread, SLOT(slt_From_Main(::myType)), Qt::QueuedConnection);m_myThread->start();
}QTThreads::~QTThreads()
{}
void QTThreads::slt_From_Worker(qreal l_rValue)
{
qDebug() << "slt_From_Worker() " << l_rValue;}
void QTThreads::slt_From_Worker(myType l_myTypeVar)
{
qDebug() << "slt_From_Worker() enum "<<l_myTypeVar;}
////////////////////////////////////////////////
////////////////////////////////////////////////
////////////////////////////////////////////////
MyThread::MyThread(QWidget * parent)
:m_bExit(false)
{
m_parent = parent;connect(this, SIGNAL(sgn_To_MainThread(qreal))
,m_parent, SLOT(slt_From_Worker(qreal)), Qt::QueuedConnection);connect(this, SIGNAL(sgn_To_MainThread(::myType))
,m_parent, SLOT(slt_From_Worker(::myType)));}
void MyThread::run()
{
quint32 nCount = 0;
qDebug()<< "thread Started";while(!m_bExit)
{
qDebug()<< "working ... " << nCount++;
emit sgn_To_MainThread(((qreal)nCount)/2);
emit sgn_To_MainThread(def);msleep(1000);
if(nCount>500)
nCount = 0;
}
qDebug()<< "thread Stopped";
}@ -
wrote on 10 Aug 2011, 19:28 last edited by
I am not sure, but my guess is that you have to "register your enum":http://developer.qt.nokia.com/doc/qt-4.7/qmetatype.html
-
wrote on 10 Aug 2011, 19:36 last edited by
Thank you, but I already tried that. I removed it from the sample code as it didn't help.
-
wrote on 10 Aug 2011, 22:08 last edited by
To cite from "qtforum":http://www.qtforum.org/article/32927/connect-with-enum-as-parameter.html
@
enum myType
{
abc
,def
,ghi
};Q_DECLARE_METATYPE(myType);
// somewhere in your code before you do the connect:
qRegisterMetaType<myType>( "myType" );
@You must register the type.
Did you try to leave out the default namespace scope "::" from the signal signature and the connect?
-
wrote on 11 Aug 2011, 07:47 last edited by
Another good idea would be to not have the signals on your QThread subclass itself. Instead make a worker object derived from QObject that does the actual work in the context of your thread. That way you can be sure that it will use a queued connection since the sender and receiver will have affinity to different threads.
-
wrote on 11 Aug 2011, 17:04 last edited by
Thank you Volker, I had a couple of problems I forgot about the Q_DECLARE_METATYPE(myType);
and I don't' think I was never consistent with the global scope specifier. Mixing doesn't work but if you always use one or the other it works.[edit] forgot to mention that you also have to use a worker object
For those who follow below is the working code.
@#ifndef QTTHREADS_H
#define QTTHREADS_H#include <QtGui/QMainWindow>
#include <QThread>
#include "ui_qtthreads.h"enum myType
{
abc
,def
,ghi
};
//Q_ENUMS(myType);
Q_DECLARE_METATYPE ( myType );class myWorker : public QObject
{
Q_OBJECTpublic:
myType m_myTypeVar;public:
void SendSignals(int nCount);
signals:
void sgn_To_MainThread(qreal rValue);
#ifdef WITH_GLOBAL_SCOPE
void sgn_To_MainThread(::myType l_myTypeVar);
#else
void sgn_To_MainThread(myType l_myTypeVar);
#endif};
class MyThread : public QThread
{
Q_OBJECT
public:MyThread(QWidget * parent);
QWidget * m_parent;myWorker * m_pMyWorkerObject;
protected:
void run();
bool m_bExit;};
class QTThreads : public QMainWindow
{
Q_OBJECTpublic:
QTThreads(QWidget parent = 0, Qt::WFlags flags = 0);
~QTThreads();
MyThread m_myThread;
myType m_myTypeVar;private:
Ui::QTThreadsClass ui;
public slots:
void slt_From_Worker(qreal rValue);#ifdef WITH_GLOBAL_SCOPE
void slt_From_Worker(::myType l_myTypeVar);
#else
void slt_From_Worker(myType l_myTypeVar);
#endif
};#endif // QTTHREADS_H
@@#include "qtthreads.h"
#include <QDebug>QTThreads::QTThreads(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
, m_myTypeVar(abc)
{m_myThread = new MyThread(this);
ui.setupUi(this);m_myThread->start();
}QTThreads::~QTThreads()
{}
void QTThreads::slt_From_Worker(qreal l_rValue)
{
qDebug() << "slt_From_Worker() " << l_rValue;}
#ifdef WITH_GLOBAL_SCOPE
void QTThreads::slt_From_Worker(::myType l_myTypeVar)
#else
void QTThreads::slt_From_Worker(myType l_myTypeVar)
#endif
{
qDebug() << "slt_From_Worker() enum "<<l_myTypeVar;}
////////////////////////////////////////////////
////////////////////////////////////////////////
////////////////////////////////////////////////
MyThread::MyThread(QWidget * parent)
:m_bExit(false)
{
#ifdef WITH_GLOBAL_SCOPE
qRegisterMetaType<::myType>( "::myType" );
#else
qRegisterMetaType<myType>( "myType" );
#endif
m_parent = parent;m_pMyWorkerObject = new myWorker();
connect(m_pMyWorkerObject, SIGNAL(sgn_To_MainThread(qreal))
,m_parent, SLOT(slt_From_Worker(qreal)), Qt::QueuedConnection);#ifdef WITH_GLOBAL_SCOPE
connect(m_pMyWorkerObject, SIGNAL(sgn_To_MainThread(::myType))
,m_parent, SLOT(slt_From_Worker(::myType)), Qt::QueuedConnection);
#else
connect(m_pMyWorkerObject, SIGNAL(sgn_To_MainThread(myType))
,m_parent, SLOT(slt_From_Worker(myType))/, Qt::QueuedConnection/);
#endif}
void MyThread::run()
{
quint32 nCount = 0;
qDebug()<< "thread Started";while(!m_bExit)
{
qDebug()<< "Sending ... " << nCount++;
m_pMyWorkerObject->SendSignals(nCount);
msleep(1000);
if(nCount>500)
nCount = 0;
}
qDebug()<< "thread Stopped";
}void myWorker::SendSignals(int nCount)
{
emit sgn_To_MainThread(((qreal)nCount)/2);
emit sgn_To_MainThread(::ghi);}@
1/6