Unsolved it troubles me !!!! QserialPort
-
a thread problme appear in my code
STATUS/1 @ init, L120: BaudRate: 230400QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0x2952c7b8), parent's thread is QThread(0x259e38f0), current thread is QThread(0x14cc2e0)my code :
HardDriver*
PlatformManager::addHardDriver(uint8_t driver_type, const char* device_port,
uint32_t baudrate)
{
#ifdef QT
if (driver_type == PlatformManager::SERIAL_DEVICE)
{QThread* serialEventThread = new QThread; QHardDriver* driver = new QHardDriver(0, device_port, baudrate); driver->moveToThread(serialEventThread); QObject::connect(serialEventThread, SIGNAL(started()), driver, SLOT(init())); QObject::connect(serialEventThread, SIGNAL(finished()), serialEventThread, SLOT(deleteLater())); serialEventThread->start(); QThread::msleep(100); return driver;
}
void
QHardDriver::init()
{
initLock.lock();
if (this->getDeviceStatus())
{
initLock.unlock();
return;
}port = new QSerialPort(QString(portName));
if (port != 0)
{
if (port->isOpen())
port->close();
port->setBaudRate(baudrate);
port->setParity(QSerialPort::NoParity);
port->setDataBits(QSerialPort::Data8);
port->setStopBits(QSerialPort::OneStop);
port->setFlowControl(QSerialPort::NoFlowControl);
if (port->open(QIODevice::ReadWrite))
{
DSTATUS("port %s open success", port->portName().toLocal8Bit().data());
setDeviceStatus(true);
DSTATUS("Read buf size: %d", port->readBufferSize());
}
else
{
DERROR("fail to open port %s", port->portName().toLocal8Bit().data());
setDeviceStatus(false);
}
DSTATUS("BaudRate: %d", port->baudRate());
}
initLock.unlock();
}
but run there it throws a problem
//! Serial Device call: last link in the send pipeline
DERROR("*****1");
ans = deviceDriver->send(buf, pHeader->length); // throws Cannot create children for a parent that is in a different thread.
//(Parent is QSerialPort(0x2952c7b8), parent's thread is
//QThread(0x259e38f0), current thread is QThread(0x14cc2e0) -
This post is deleted! -
Hi and welcome to devnet,
What does happen in
deviceDriver->send
?
Where are you calling if from ?What version of Qt are you using ?
What OS are you running ? -
hi ~ thank you first
it works on windows QT5.1HardDriver* deviceDriver;
QHardDriver::send(const uint8_t* buf, size_t len)
{
sendLock.lock();
size_t sent = 0;
if (port != 0)
{
// if (port->isOpen())
while (sent != len)
{
sent += port->write(reinterpret_cast<const char*>(buf + sent), len);
port->waitForBytesWritten(2);
}
sendLock.unlock();
return sent;
}
else
{
sendLock.unlock();
return 0;
}
sendLock.unlock();
return sent;
} -
@quelle.shen said in it troubles me !!!! QserialPort:
it works on windows QT5.1
QSerialPort was very new in Qt 5.1. I strongly recommend updating to a newer version.
That may not solve your problem, but avoid others.
-
@aha_1980
maybe you are right ,but i have to run it on Qt5.1
the problem still troubles me !! -
You seem to move your serial port stuff in another thread and then calling its methods directly, is that the case ?
-
@SGaist
yes ,but i dont know how to revision my code. -
@SGaist
why just call port->write() will trows the problem ?
i add some code but it doesnt work .
i add code :
QThread* serialEventThread = new QThread;
QHardDriver* driver = new QHardDriver(0, device_port, baudrate);
//driver->init();
driver->moveToThread(serialEventThread);
driver->port->moveToThread(serialEventThread);
//Qt:: DirectConnection
QObject::connect(serialEventThread, SIGNAL(started()), driver,
SLOT(init()));
QObject::connect(serialEventThread, SIGNAL(finished()), driver, SLOT(deleteLater()));
QObject::connect(serialEventThread, SIGNAL(finished()), serialEventThread,
SLOT(deleteLater()));
serialEventThread->start();
QThread::msleep(100);
return driver;
-
@quelle.shen said in it troubles me !!!! QserialPort:
QObject::connect(serialEventThread, SIGNAL(started()), driver,
SLOT(init()));From our direct messages...
hmm.... When you call deviceDriver->send(), I assume that send() is a member of deviceDriver?. But deviceDriver is in a different thread! in addHardDriver() you return a device driver that was moved to a different thread. What you need to do now is create another slot/signal connection to send your write-data to your device driver via a call to a signal. Somthing like:
QObject::connect(this, SIGNAL(send_to_driver(QVector data)), driver,SLOT(data_to_send(QVector data)));
Then instead of doing driver->write() you do send_to_driver(data). I used QVector in my example - not but you can put what ever Q<data type> you want...Note: You cannot ever safely call members directly in the device driver ever again once you have moved it into another thread :p ... this is exactly what slot/signals are for. Doing so breaks the thread boundaries and Qt rightfully complains. If you call a member function directly then everything that occurs in that function call occurs in the calling thread and not the thread that you moved that class into. Does that make sense?
-
@code_fodder
thanks reply for my question ,you are right .
i think your advice is good way to solve my problem .