deleting serialPort causes this message in debug builds:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread c0a528. Receiver '' (of type 'QSerialPort') was created in thread c76850", file kernel\qcoreapplication.cpp, line 532
The actual error is triggered in ~QSerialReader when Main window is closed. Here's the code.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
runnerThread=new QThread(this);
/* - connect thread start signal to qrunnerthread's runLoop()
this starts the main job loop
- connect thread finished signal to mainwindows' deleteLater
to ensure proper deletion */
qDataReader = new QDataReader();
connect(runnerThread, SIGNAL(started()), qRunnerThread, SLOT(runLoop()));
connect(runnerThread, SIGNAL(finished()), this, SLOT(deleteLater()));
qDataReader->moveToThread(runnerThread);
runnerThread.start();
}
MainWindow::~MainWindow()
{
runnerThread->exit();
}
//slot that runs when thread is started
void QDataReader::runLoop() {
/* this code runs in different thread than QDataReader */
//serialPort parent will be QThread (runnerThread)
serialReader=new QSerialReader(this);
while(doStuff) {
QString data=serialReader.readData();
emit dataReceived(data);
}
}
QDataReader::~QDataReader() {
delete runner;
}
QSerialReader::QSerialReader(QObject* parent) {
//serialPort parent will be QSerialReader
serialPort = new QSerialPort(this);
}
QSerialReader::~QSerialReader() {
/*
deleting serialPort causes this message in debug builds:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread c0a528. Receiver '' (of type 'QSerialPort') was created in thread c76850", file kernel\qcoreapplication.cpp, line 532
*/
delete serialPort;
}
edit1: peppe's suggestion:
If I change QSerialReader to a member in QDataReader the problem is gone. BUT when opening port with QSerialPort::open this error comes up:
QObject: Cannot create children for a parent that is in a different thread. (Parent is QSerialPort(0xdf6930), parent's thread is QThread(0xd8a528), current thread is QThread(0xdf6850) QObject: Cannot create children for a parent that is in a different thread. (Parent is QSerialPort(0xdf6930), parent's thread is QThread(0xd8a528), current thread is QThread(0xdf6850)
QSerialPort::open(xx) is called inside serialReader.readData();
So still... some nasty problem. I did not have issues like this when I coded in Java a few years ago.
stack trace when CSerialReader::openPort is called. this calls QSerialPort::open. Clearly this is run in other thread than main.
0 CSerialReader::openPort serialreader.cpp 480 0xff7211
1 CSerialReader::readData serialreader.cpp 209 0xff4e1d
2 QDataReader::runLoop qdatareader.cpp 138 0xffa3fe
3 QDataReader::qt_static_metacall moc_qdatareader.cpp 62 0x1040824
4 QMetaObject::activate qobject.cpp 3539 0x669b0e14
5 QThread::started moc_qthread.cpp 113 0x66a29979
6 QThreadPrivate::start qthread_win.cpp 345 0x66816918
7 _callthreadstartex threadex.c 314 0xf71a293
8 _threadstartex threadex.c 297 0xf71a224
9 BaseThreadInitThunk kernel32 0x74cd3677
10 __RtlUserThreadStart ntdll32 0x76f9c002
11 _RtlUserThreadStart ntdll32 0x76f9bfd5
stack trace when CSerialReader is created (as member variable). This is called in main thread.
0 CSerialReader::CSerialReader Runner.cpp 48 0x9d3d14
1 QDataReader::QDataReader qdatareader.cpp 10 0x9d8fa4
2 MainWindow::MainWindow mainwindow.cpp 72 0x9c61eb
3 main main.cpp 105 0x9c4adc
4 WinMain qtmain_win.cpp 131 0xa273ba
5 __tmainCRTStartup crtexe.c 547 0xa269e0
6 WinMainCRTStartup crtexe.c 371 0xa2676f
7 BaseThreadInitThunk kernel32 0x74cd3677
8 __RtlUserThreadStart ntdll32 0x76f9c002
9 _RtlUserThreadStart ntdll32 0x76f9bfd5
serialReader=new QSerialReader(this);
Don't do this. Parents and children must live in the same thread. In your case, the parent (QThread) is living in its own thread, and the child (QSerialReader) is living in the thread you spawned. Can't you just allocate it on the stack instead?