Illegal attempt to connectthe class that is in a different thread that the QML engine
-
Hi,
I have this class to handle incoming CAN Frames. I want to emit these frames to be printed in a TextArea, but I am getting this error:
QML debugging is enabled. Only use this in a safe environment. QML thread running Connected to CAN interface: vcan0 WARNING: QApplication was not created in the main() thread. qrc:/Depoortere_Visualization_2/main.qml:220:9: QML Connections: Implicitly defined onFoo properties in Connections are deprecated. Use this syntax instead: function onFoo(<arguments>) { ... } QQmlEngine: Illegal attempt to connect to CANHandler(0x7ffe0ef65080) that is in a different thread than the QML engine QQmlApplicationEngine(0x7fc4b6d42ac0.
I have tried numerous thing to get this working, but ended with the same error each time. I am running this in separate threads to be able to continuously read incoming CAN frames. Anybody have any idea on a fix.
This is my main.cpp:
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include <iostream> #include <thread> #include "CANHandler.h" #include "TranslationHandler.h" int qmlFunction(int argc, char *argv[], CANHandler *canHandler) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; TranslationHandler transHandler; engine.rootContext()->setContextProperty("transHandler", &transHandler); engine.rootContext()->setContextProperty("canHandler", canHandler); const QUrl url("qrc:/Depoortere_Visualization_2/main.qml"); QObject::connect( &engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); if (engine.rootObjects().isEmpty()) { std::cerr << "QML failed to load." << std::endl; return -1; } return app.exec(); } int main(int argc, char *argv[]) { CANHandler canHandler; std::thread canThread([&]() { QObject::connect(&canHandler, &CANHandler::newFrameReceived, [&](const QString &frame) { std::cout << frame.toStdString() << std::endl; }); canHandler.mainFunction(); }); std::thread qmlThread(qmlFunction, argc, argv, &canHandler); if (canThread.joinable()) { std::cout << "CAN thread running" << std::endl; canThread.join(); } if (qmlThread.joinable()) { std::cout << "QML thread running" << std::endl; qmlThread.join(); } return 0; }
-
-
@MaximBozek said in Illegal attempt to connectthe class that is in a different thread that the QML engine:
@J-Hilk Thanks for the help...
You're welcome.
It might look silly, because its answered as a meme, but its generally the problem and solution.
your CANHandler is created as the first thing on the stack. Way later the QGuiApplication is created on the stack of a different thread even.
-
Yes, but I want these running in different threads. I read and saw some material on Signals and slots, but I haven't really figured out how it works completaly. I think it should be possible with signals and slots.
-
Why can't you simply do what @J-Hilk told you to do - create a QGuiApplication first.