Why is a thread attempted to be created, when a bool value is accessed?
-
QSerialPort m_ser_1; bool open = m_ser_1.open(QIODevice::ReadWrite); bool isWritable = m_ser_1.isWritable();
results in
QObject: Cannot create children for a parent that is in a different thread. (Parent is QSerialPort(0x7ffce38cbd10), parent's thread is QThread(0x55bf31802830), current thread is QThread(0x55bf318a61f0)
according to debug, error occurs after
bool isWritable = m_ser_1.isWritable();
-
@Christian-Ehrlicher said in Why is a thread attempted to be created, when a bool value is accessed?:
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
maybe somewhere that call moveToThread()
When you would simply do what I suggested you would not have the problems but since you're ignoring me - happy coding.
if i was ignoring you, then i would not have replied to you
i keep going back over everything said, trying to figure out what was said.
tried to
class CControls : public QSerialPort
but it gives
/home/michaeleric/Qt_Creator_Projects/QSerialPortTest/CControls.cpp:5: error: type ‘QObject’ is not a direct base of ‘CControls’ 5 | CControls::CControls() : QObject() | ^~~~~~~
and it was a wild guess of making m_ser_1 a child of CControls
making
QSerialPort m_ser_1
a child of CControls, makes no sense
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
tried to
class CControls : public QSerialPortbut it gives
/home/michaeleric/Qt_Creator_Projects/QSerialPortTest/CControls.cpp:5: error: type ‘QObject’ is not a direct base of ‘CControls’
5 | CControls::CControls() : QObject()
| ^~~~~~~seems like you forgot to change your cpp file to the new baseclass, now that you have changed it.
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
and it was a wild guess of making m_ser_1 a child of CControls
It was not, its the root of your problems, actually the root of your problems is using waitForXXX functions, but thats an other topic.
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
making
QSerialPort m_ser_1a child of CControls, makes no sense
do you think that changing the base class from QObject to QSerialPort would somehow reparent your serialport instance?
BaseClass != parent/child relation
-->
CControls::CControls() : QObject(), m_ser_1(this) { }
-
QSerialPort m_ser_1; bool open = m_ser_1.open(QIODevice::ReadWrite); bool isWritable = m_ser_1.isWritable();
results in
QObject: Cannot create children for a parent that is in a different thread. (Parent is QSerialPort(0x7ffce38cbd10), parent's thread is QThread(0x55bf31802830), current thread is QThread(0x55bf318a61f0)
according to debug, error occurs after
bool isWritable = m_ser_1.isWritable();
@micha_eleric
Are you certain it occurs on linem_ser_1.isWritable();
? Could "after" mean at some later time? If you putqDebug() << "Called isWritable()
;` immediately after can you show the error message comes before then?m_ser_1
is perhaps a class member variable? Do you access it elsewhere than shown above in your code? -
let me guess, your
QSerialPort m_ser_1;
is actually a member (stack) variable of a class instance that you used "moveToThread" on ? -
@micha_eleric
Are you certain it occurs on linem_ser_1.isWritable();
? Could "after" mean at some later time? If you putqDebug() << "Called isWritable()
;` immediately after can you show the error message comes before then?m_ser_1
is perhaps a class member variable? Do you access it elsewhere than shown above in your code?bool open = m_ser_1.open(QIODevice::ReadWrite); bool isWritable = m_ser_1.isWritable(); qDebug() << "Called " << m_ser_1.isWritable();
QObject: Cannot create children for a parent that is in a different thread. (Parent is QSerialPort(0x7fff6c8d2c50), parent's thread is QThread(0x564d50639830), current thread is QThread(0x564d506dd620) Called true
gave compile error
qDebug() << "Called isWritable();
-
let me guess, your
QSerialPort m_ser_1;
is actually a member (stack) variable of a class instance that you used "moveToThread" on ?@J-Hilk said in Why is a thread attempted to be created, when a bool value is accessed?:
let me guess, your
QSerialPort m_ser_1;
is actually a member (stack) variable of a class instance that you used "moveToThread" on ?not in my code
-
@J-Hilk said in Why is a thread attempted to be created, when a bool value is accessed?:
let me guess, your
QSerialPort m_ser_1;
is actually a member (stack) variable of a class instance that you used "moveToThread" on ?not in my code
What exact qt version do you use? Please provide a minimal, compilable example of your issue - according to your description a simple main() with opening a QSerialPort should be enough.
-
What exact qt version do you use? Please provide a minimal, compilable example of your issue - according to your description a simple main() with opening a QSerialPort should be enough.
@Christian-Ehrlicher said in Why is a thread attempted to be created, when a bool value is accessed?:
What exact qt version do you use? Please provide a minimal, compilable example of your issue - according to your description a simple main() with opening a QSerialPort should be enough.
Qt Creator 4.11.0
Based on Qt 5.12.8 (GCC 9.3.0, 64 bit)Copyright 2008-2019 The Qt Company Ltd. All rights reserved.
-
@Christian-Ehrlicher said in Why is a thread attempted to be created, when a bool value is accessed?:
What exact qt version do you use? Please provide a minimal, compilable example of your issue - according to your description a simple main() with opening a QSerialPort should be enough.
Qt Creator 4.11.0
Based on Qt 5.12.8 (GCC 9.3.0, 64 bit)Copyright 2008-2019 The Qt Company Ltd. All rights reserved.
@micha_eleric We don't care about the version of your IDE but the Qt version you build your program with.
-
@micha_eleric We don't care about the version of your IDE but the Qt version you build your program with.
@Christian-Ehrlicher it is the only place i found a version
-
What exact qt version do you use? Please provide a minimal, compilable example of your issue - according to your description a simple main() with opening a QSerialPort should be enough.
@Christian-Ehrlicher said in Why is a thread attempted to be created, when a bool value is accessed?:
What exact qt version do you use? Please provide a minimal, compilable example of your issue - according to your description a simple main() with opening a QSerialPort should be enough.
working on a minimum code, but is throwing
:-1: error: collect2: error: ld returned 1 exit status
-
QT -= gui QT += widgets QT += core serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += debug CONFIG += c++11 console CONFIG -= app_bundle # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ CControls.cpp \ CGUI.cpp \ CThreadController.cpp \ main.cpp HEADERS += \ CControls.h \ CGUI.h \ CThreadController.h \ ui_main.h FORMS += \ mainwindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target DISTFILES +=
main.cpp
#include "CGUI.h" #include "CThreadController.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); CControls con; //CCONTROLS_H CGUI gui; //CGUI CThreadController thrCon; //CThreadController gui.SetController(&thrCon); thrCon.SetC1(&con); thrCon.startThreads(); gui.show(); return a.exec(); }
CGUI.h
// cgui #ifndef CCLASS2_H #define CCLASS2_H #include <iostream> #include <QMainWindow> #include <QObject> #include <QThread> #include "ui_main.h" class CThreadController; class CGUI : public QMainWindow { Q_OBJECT public: // data Ui_MainWindow *m_ui; CThreadController *m_threadcontroller; //thread controller // constructor CGUI(QWidget *parent = 0); // destructor virtual ~CGUI(); // get/set void SetController(CThreadController *controller); // functions void Button(); }; #endif // CCLASS2_H
CGUI.cpp
// cgui #include "CGUI.h" #include "CThreadController.h" CGUI::CGUI(QWidget *parent): QMainWindow(parent) { std::cout << "CClass2 "<< '\n' << std::flush; QString qs = QString::number((long long)(QThread::currentThreadId()), 16); std::cout << qs.toStdString() << '\n' << std::flush; m_ui = new Ui_MainWindow(); m_ui->setupUi(this); connect(m_ui->pushButton, &QPushButton::clicked, this, &CGUI::Button); } CGUI::~CGUI() { } // get/set void CGUI::SetController(CThreadController *controller) { m_threadcontroller = controller; } // functions void CGUI::Button() { std::cout << "Button "<< '\n' << std::flush; QString qs = QString::number((long long)(QThread::currentThreadId()), 16); std::cout << qs.toStdString() << '\n' << std::flush; emit m_threadcontroller->EmitPortName_1(); }
CThreadController.h
#ifndef CCLASS3_H #define CCLASS3_H #include <QObject> #include <QThread> #include "CControls.h" #include "CGUI.h" class CThreadController : public QThread { Q_OBJECT CControls *m_controls; QThread* m_threadClass1; public: CThreadController(); CThreadController(QObject *parent); // destructor ~CThreadController(); // get/set void SetC1(CControls *c1); // function void startThreads(); signals: void EmitPortName_1(); }; #endif // CCLASS3_H
CThreadController.cpp
#include "CThreadController.h" CThreadController::CThreadController() { m_threadClass1 = new QThread(); } CThreadController::CThreadController(QObject *parent = 0) : QThread(parent) { m_threadClass1 = new QThread(); } CThreadController::~CThreadController() { } // get/set void CThreadController::SetC1(CControls *c1) { std::cout << "SetC1 "<< '\n' << std::flush; QString qs = QString::number((long long)(QThread::currentThreadId()), 16); std::cout << qs.toStdString() << '\n' << std::flush; m_controls = c1; m_controls->moveToThread(m_threadClass1); connect(m_threadClass1, &QThread::finished, m_controls, &QObject::deleteLater); connect(m_threadClass1, &QThread::finished, m_threadClass1, &QThread::deleteLater); m_threadClass1->start(); } // function void CThreadController::startThreads() { connect(this, &CThreadController::EmitPortName_1, m_controls, &CControls::SetPortName_1); }
CControls.h
//CCONTROLS_H #ifndef CCLASS1_H #define CCLASS1_H #include <iostream> #include <QObject> #include <QSerialPort> #include <QThread> class CControls : public QObject { Q_OBJECT private: QSerialPort m_ser_1; public: CControls(); CControls(QObject *parent); ~CControls(); public slots: void SetPortName_1(); }; #endif // CCLASS1_H
CControls.cpp
//CCONTROLS_H #include "CControls.h" //#include "ui_CClass1.h" CControls::CControls() : QObject() { } CControls::CControls(QObject *parent = 0) : QObject(parent) { } CControls::~CControls() { } void CControls::SetPortName_1() { std::cout << "SetPortName_1 "<< '\n' << std::flush; QString qs = QString::number((long long)(QThread::currentThreadId()), 16); std::cout << qs.toStdString() << '\n' << std::flush; m_ser_1.close(); m_ser_1.setPortName("/dev/ttyACM0"); //m_ser_1. bool open = m_ser_1.open(QIODevice::ReadWrite); bool isWritable = m_ser_1.isWritable(); std::cout << "open = " << open << '\n' << std::flush; std::cout << "isWritable = " << isWritable << '\n' << std::flush; }
snippet of larger program that compiles, but snippet throws these errors:
:-1: error: CGUI.o: in function `CGUI::Button()': /home/michaeleric/Qt_Creator_Projects/QSerialPortTest/CGUI.cpp:31: error: undefined reference to `CThreadController::EmitPortName_1()' :-1: error: CThreadController.o: in function `CThreadController::startThreads()': /home/michaeleric/Qt_Creator_Projects/QSerialPortTest/CThreadController.cpp:34: error: undefined reference to `CThreadController::EmitPortName_1()' :-1: error: collect2: error: ld returned 1 exit status
i have looked at larger program, and snippet side by side, every way i could think of, but can not find what is throwing compile error.
-
QT -= gui QT += widgets QT += core serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += debug CONFIG += c++11 console CONFIG -= app_bundle # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ CControls.cpp \ CGUI.cpp \ CThreadController.cpp \ main.cpp HEADERS += \ CControls.h \ CGUI.h \ CThreadController.h \ ui_main.h FORMS += \ mainwindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target DISTFILES +=
main.cpp
#include "CGUI.h" #include "CThreadController.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); CControls con; //CCONTROLS_H CGUI gui; //CGUI CThreadController thrCon; //CThreadController gui.SetController(&thrCon); thrCon.SetC1(&con); thrCon.startThreads(); gui.show(); return a.exec(); }
CGUI.h
// cgui #ifndef CCLASS2_H #define CCLASS2_H #include <iostream> #include <QMainWindow> #include <QObject> #include <QThread> #include "ui_main.h" class CThreadController; class CGUI : public QMainWindow { Q_OBJECT public: // data Ui_MainWindow *m_ui; CThreadController *m_threadcontroller; //thread controller // constructor CGUI(QWidget *parent = 0); // destructor virtual ~CGUI(); // get/set void SetController(CThreadController *controller); // functions void Button(); }; #endif // CCLASS2_H
CGUI.cpp
// cgui #include "CGUI.h" #include "CThreadController.h" CGUI::CGUI(QWidget *parent): QMainWindow(parent) { std::cout << "CClass2 "<< '\n' << std::flush; QString qs = QString::number((long long)(QThread::currentThreadId()), 16); std::cout << qs.toStdString() << '\n' << std::flush; m_ui = new Ui_MainWindow(); m_ui->setupUi(this); connect(m_ui->pushButton, &QPushButton::clicked, this, &CGUI::Button); } CGUI::~CGUI() { } // get/set void CGUI::SetController(CThreadController *controller) { m_threadcontroller = controller; } // functions void CGUI::Button() { std::cout << "Button "<< '\n' << std::flush; QString qs = QString::number((long long)(QThread::currentThreadId()), 16); std::cout << qs.toStdString() << '\n' << std::flush; emit m_threadcontroller->EmitPortName_1(); }
CThreadController.h
#ifndef CCLASS3_H #define CCLASS3_H #include <QObject> #include <QThread> #include "CControls.h" #include "CGUI.h" class CThreadController : public QThread { Q_OBJECT CControls *m_controls; QThread* m_threadClass1; public: CThreadController(); CThreadController(QObject *parent); // destructor ~CThreadController(); // get/set void SetC1(CControls *c1); // function void startThreads(); signals: void EmitPortName_1(); }; #endif // CCLASS3_H
CThreadController.cpp
#include "CThreadController.h" CThreadController::CThreadController() { m_threadClass1 = new QThread(); } CThreadController::CThreadController(QObject *parent = 0) : QThread(parent) { m_threadClass1 = new QThread(); } CThreadController::~CThreadController() { } // get/set void CThreadController::SetC1(CControls *c1) { std::cout << "SetC1 "<< '\n' << std::flush; QString qs = QString::number((long long)(QThread::currentThreadId()), 16); std::cout << qs.toStdString() << '\n' << std::flush; m_controls = c1; m_controls->moveToThread(m_threadClass1); connect(m_threadClass1, &QThread::finished, m_controls, &QObject::deleteLater); connect(m_threadClass1, &QThread::finished, m_threadClass1, &QThread::deleteLater); m_threadClass1->start(); } // function void CThreadController::startThreads() { connect(this, &CThreadController::EmitPortName_1, m_controls, &CControls::SetPortName_1); }
CControls.h
//CCONTROLS_H #ifndef CCLASS1_H #define CCLASS1_H #include <iostream> #include <QObject> #include <QSerialPort> #include <QThread> class CControls : public QObject { Q_OBJECT private: QSerialPort m_ser_1; public: CControls(); CControls(QObject *parent); ~CControls(); public slots: void SetPortName_1(); }; #endif // CCLASS1_H
CControls.cpp
//CCONTROLS_H #include "CControls.h" //#include "ui_CClass1.h" CControls::CControls() : QObject() { } CControls::CControls(QObject *parent = 0) : QObject(parent) { } CControls::~CControls() { } void CControls::SetPortName_1() { std::cout << "SetPortName_1 "<< '\n' << std::flush; QString qs = QString::number((long long)(QThread::currentThreadId()), 16); std::cout << qs.toStdString() << '\n' << std::flush; m_ser_1.close(); m_ser_1.setPortName("/dev/ttyACM0"); //m_ser_1. bool open = m_ser_1.open(QIODevice::ReadWrite); bool isWritable = m_ser_1.isWritable(); std::cout << "open = " << open << '\n' << std::flush; std::cout << "isWritable = " << isWritable << '\n' << std::flush; }
snippet of larger program that compiles, but snippet throws these errors:
:-1: error: CGUI.o: in function `CGUI::Button()': /home/michaeleric/Qt_Creator_Projects/QSerialPortTest/CGUI.cpp:31: error: undefined reference to `CThreadController::EmitPortName_1()' :-1: error: CThreadController.o: in function `CThreadController::startThreads()': /home/michaeleric/Qt_Creator_Projects/QSerialPortTest/CThreadController.cpp:34: error: undefined reference to `CThreadController::EmitPortName_1()' :-1: error: collect2: error: ld returned 1 exit status
i have looked at larger program, and snippet side by side, every way i could think of, but can not find what is throwing compile error.
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
CThreadController::EmitPortName_1()
You defined this function but there's no implementation for it.
If you want to be that this is a slot you should declare it as a such.Also why is CThreadController a QThread?
Since m_ser_1 is not a child of CControls QObject::moveToThread() will not move it to the new thread.
And as always - there is no need for a separate thread here.
-
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
CThreadController::EmitPortName_1()
You defined this function but there's no implementation for it.
If you want to be that this is a slot you should declare it as a such.Also why is CThreadController a QThread?
Since m_ser_1 is not a child of CControls QObject::moveToThread() will not move it to the new thread.
And as always - there is no need for a separate thread here.
@Christian-Ehrlicher the need is the gui is to run on a different thread than the controls
-
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
CThreadController::EmitPortName_1()
You defined this function but there's no implementation for it.
If you want to be that this is a slot you should declare it as a such.Also why is CThreadController a QThread?
Since m_ser_1 is not a child of CControls QObject::moveToThread() will not move it to the new thread.
And as always - there is no need for a separate thread here.
@Christian-Ehrlicher when
void CGUI::Button()
calls
emit m_threadcontroller->EmitPortName_1();
it is linked to
connect(this, &CThreadController::EmitPortName_1, m_controls, &CControls::SetPortName_1);
which calls
void CControls::SetPortName_1()
which is suppose to be on a different thread than
void CGUI::Button()
-
@Christian-Ehrlicher the need is the gui is to run on a different thread than the controls
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
the need is the gui is to run on a different thread than the controls
Why? Qt is asynchronous...
-
@Christian-Ehrlicher when
void CGUI::Button()
calls
emit m_threadcontroller->EmitPortName_1();
it is linked to
connect(this, &CThreadController::EmitPortName_1, m_controls, &CControls::SetPortName_1);
which calls
void CControls::SetPortName_1()
which is suppose to be on a different thread than
void CGUI::Button()
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
which calls
void CControls::SetPortName_1()which is suppose to be on a different thread than
I never said something else. Please properly read my answer, take a look when a member is a child of a QObject and make m_ser_1 a child of your CControls.
-
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
the need is the gui is to run on a different thread than the controls
Why? Qt is asynchronous...
@Christian-Ehrlicher because the gui locks up, until all of the controls is finished. graphics on gui will not update
-
@Christian-Ehrlicher because the gui locks up, until all of the controls is finished. graphics on gui will not update
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
because the gui locks up, until all of the controls is finished. graphics on gui will not update
Then you're doing something wrong but a thread is also the wrong solution here.
-
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
because the gui locks up, until all of the controls is finished. graphics on gui will not update
Then you're doing something wrong but a thread is also the wrong solution here.
@Christian-Ehrlicher said in Why is a thread attempted to be created, when a bool value is accessed?:
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
because the gui locks up, until all of the controls is finished. graphics on gui will not update
Then you're doing something wrong but a thread is also the wrong solution here.
it maybe the wrong solution for this snippet, but is needed for the larger program. this snippet is a small part of a " thread attempted to be created, when a bool value is accessed"
-
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
CThreadController::EmitPortName_1()
You defined this function but there's no implementation for it.
If you want to be that this is a slot you should declare it as a such.Also why is CThreadController a QThread?
Since m_ser_1 is not a child of CControls QObject::moveToThread() will not move it to the new thread.
And as always - there is no need for a separate thread here.
@Christian-Ehrlicher said in Why is a thread attempted to be created, when a bool value is accessed?:
@micha_eleric said in Why is a thread attempted to be created, when a bool value is accessed?:
CThreadController::EmitPortName_1()
You defined this function but there's no implementation for it.
if EmitPortName_1() is defined, then it throws a moc compile error
If you want to be that this is a slot you should declare it as a such.
thought EmitPortName_1() was a signals
Also why is CThreadController a QThread?
because CThreadController is what controls [starts, makes, do thread stuff]
Since m_ser_1 is not a child of CControls QObject::moveToThread() will not move it to the new thread.
where is m_ser_1 attempted to be moveToThread?
And as always - there is no need for a separate thread here.