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