1 Attachment(s)
QTcpSocket as class member of QThread Issue
All,
In below codes, I get a QObject warning message during running:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x9cb3f98), parent's thread is BackServer(0x9ca2640), current thread is QThread(0x9c46378)
Code:
public:
......
public slots:
protected:
void run();
private slots:
void slot_newConn();
......
private:
quint16 m_port;
};
void BackServer::run(){
connect(m_ser, SIGNAL(newConnection()), SLOT(slot_newConn()), Qt::DirectionConnect);
m_ser->listen(m_ip, m_port);
exec();
}
void BackServer::slot_conn(){
m_conn=m_ser->nextPendingConnection();
}
void BackServer
::sendMsg(QString msg
){ if (m_conn){
m_conn->write(msg.toUtf8()); // < -- issue occured point
m_conn->waitForBytesWritten();
}
}
I use BackServer as a member of subclass of QMainWindow:
Code:
class MainWindow{
...
private slots:
void slot_sendMsg();
void slot_startServer();
signal:
private:
BackServer * m_backServer;
};
class MainWindow::MainWindow(...){
...
connect(ui->sendButton, SIGNAL(clicked()), SLOT(slot_sendMsg()));
...
}
class MainWindow::slot_startServer(){
...
m_backServer=new BackServer(ip, port);
connect(this,
SIGNAL(sendMsg
(QString), m_backServer,
SLOT(sendMsg
(QString);
m_backServer->start();
...
}
//
// whichever, the QObject create child thread occured!
//
class MainWindow::slot_sendMsg(){
#if 0
if (m_backServer && m_backServer->isRunning()){
m_backServer->sendMsg(ui->lineEdit->text());
}
#else
emit sendMsg(ui->lineEdit->text());
#endif
}
any suggestion?
attach is my Qtcode.
Re: QTcpSocket as class member of QThread Issue
The QThread object lives in the main thread and not the thread it controls. Thus all its slots are executed in the context of the main thread. This causes objects created in them to live in the context of the main thread as well, including the QTcpSocket object created by nextPendingConnection(). Now the tcp server object lives in the context of the worker thread as it was created in the run() method of your thread class. So the two objects (server and socket) live in different threads yet the socket is a child of the server. That causes the warning. You need to make sure the socket is created in the context of the same thread as the server object.
1 Attachment(s)
Re: QTcpSocket as class member of QThread Issue
Thank you, wysota.
According your remind, I had fixed the issue via QObject.moveToThread()! please see attachment!
Code:
void BackServer::newConn(){
m_conn=m_ser->nextPendingConnection();
...
m_conn->setParent(NULL);
}
Re: QTcpSocket as class member of QThread Issue
did that fix it? I might be missing something but isn't m_conn already in QApplication::instance()->thread()?
I thought this article was great. It's deal with database, but it is really about threads.
http://www.linuxjournal.com/article/9602
Re: QTcpSocket as class member of QThread Issue
To tanderson:
Yes, I have fixed it!
The QApplication:instance()->thread() get the main thread of application, so we can move m_conn into main thread via QObject->moveToThread(). Actually m_conn will been moved into main thread after call that.
If you want move a object into other thread except main thread, must pass the pointer of destination thread into moveToThread().
A object is live in background thread, if it created in that thread.