PDA

View Full Version : Why my object stay in main thread?



honestapple
2nd April 2013, 13:02
I wanted to create a serial port monitor thread. I used QT4.8.6 + QSerialPort(latest) on Windows XP.

I derived a CSerialPort subclass from QObject class and a subclass of QThread at first.


class CSerialPort : public QObject
{
Q_OBJECT

public:
CSerialPort();
~CSerialPort();

void printThreadID();

signals:

public slots:

private:
QSerialPort *m_spSerialPort; // serial port object
QTimer *m_tQueryTimer;
};

class CMonitorThread : public QThread
{
Q_OBJECT

public:
CMonitorThread( QObject *parent = NULL );
~CMonitorThread();
void run();

public slots:
signals:

private:

};

CSerialPort::CSerialPort()
{
// Create serial port object
m_spSerialPort = new QSerialPort();
// 1. print the thead where m_spSerialPort lived in
printThreadID();

// Timer for send command
m_tQueryTimer = new QTimer;

}

The CMonitorThread did nothing just run its event loop


CMonitorThread::CMonitorThread(QObject *parent) : QThread(parent)
{

}

CMonitorThread::~CMonitorThread()
{

}

void CMonitorThread::run()
{
this->exec();
}

Then, I declared pointers to CMonitorThread and CSerialPort in the mainwindow.


class CAnalyzerWindow : public QWidget
{
Q_OBJECT

public:
CAnalyzerWindow(QWidget * = NULL);
~CAnalyzerWindow();

signals:

public slots:

private:
CSerialPort *m_spDevPort;
CMonitorThread *m_mtPortMonitorThread;

};


In the constructor of the mainwindow, I created the instance of the CSerialPort and the CMonitorThread


CAnalyzerWindow::CAnalyzerWindow( QWidget *parent ) : QWidget( parent )
{
/* Initialize widgets and layout */
InitReceiveGroupBox();
InitSettingGroupBox();
InitScopeGroupBox();

QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget( m_gbScope, 0, 0, 1, 2 );
mainLayout->addWidget( m_gbSetting, 1, 0 );
mainLayout->addWidget( m_gbReceive, 1, 1 );

setLayout( mainLayout );
update();

/* Enumerate available serial port */
if (!enumAvailableSerialPort())
{
qDebug() << "No available ports!";
return;
}

/* Create serial port object */
m_spDevPort = new CSerialPort();
qDebug() << m_spDevPort->thread();// 2. print the thead where m_spDevPort lived in

/* Create serial port monitor thread */
m_mtPortMonitorThread = new CMonitorThread();

/* Attach serial port object to monitor thread */
m_spDevPort->moveToThread(m_mtPortMonitorThread);
/* Start thread */
m_mtPortMonitorThread->start();

// 3. print the thead where m_mtPortMonitorThread lived in
qDebug() << m_mtPortMonitorThread->currentThread();
// 4. print the thead where m_spDevPort lived in
qDebug() << m_spDevPort->thread();
// 5. print the thead where m_spSerialPort lived in
m_spDevPort->printThreadID();


connect( m_pbStart, SIGNAL( clicked() ), this, SLOT( slt_pbStart_Clicked() ) );

}


Then, I got the following output.
1.QThread(0x9b7d68)
2.QThread(0x9b7d68)
3.QThread(0x9b7d68)
4.CMonitorThread(0xff79e0)
5.QThread(0x9b7d68)

I puzzled with 4 and 5. I have used moveToThread function to move the m_spDevPort to the monitor thread, but its member m_spSerialPort still stayed in the main thread.

So, when I tried to open the serial port using signal and slot, I got the following message
"Cannot create children for a parent that is in a different thread."(only occur when I tried to open serial port)

Could anybody tell me what is the problem?

Santosh Reddy
2nd April 2013, 14:24
I puzzled with 4 and 5. I have used moveToThread function to move the m_spDevPort to the monitor thread, but its member m_spSerialPort still stayed in the main thread.
your problem is that m_spSerialPort's parent is not set.



CSerialPort::CSerialPort()
{
// Create serial port object
m_spSerialPort = new QSerialPort(this); //<<<<<<<<<<<<<<<< Pass the parent while object creation.
// 1. print the thead where m_spSerialPort lived in
printThreadID();

// Timer for send command
m_tQueryTimer = new QTimer;

}

kuzulis
2nd April 2013, 16:50
I wanted to create a serial port monitor thread. I used QT4.8.6 + QSerialPort(latest) on Windows XP.
Using the QSerialPort library is not good idea.

Is better to use - QtSerialPort (http://qt-project.org/wiki/QtSerialPort)library.

ChrisW67
3rd April 2013, 01:25
Using threads is probably unnecessary also.

honestapple
3rd April 2013, 05:29
Yes, it is QtSerialPort library.

Added after 26 minutes:

Yes, I knew that you have mention that. I am doing a USB DAQ GUI part on PC using QT4.8.6+QWT6.0.2 under Windows XP. I should receive data from device and display waveform, frequency spectrum, etc. I have made a demo without threads which could receive and send command( using timer ) at a interval, but I could not display the wavefrom in realtime. In fact, it was not that the waveform could not be displayed completly. It is sometimes good, sometimes bad. When it was bad, I knew that there are something wrong with the QwtCPointerData. Because there are many operation in main GUI thread, I wanted to tried to use monitor thread to release GUI thread from doing data receiving and sending command.