[Solved]Problem emiting a signal with and enum from a thread



  • 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_OBJECT

    public:
    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";
    }@


  • Moderators

    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



  • Thank you, but I already tried that. I removed it from the sample code as it didn't help.



  • 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?



  • 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.



  • 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_OBJECT

    public:
    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_OBJECT

    public:
    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);

    }@


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.