Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: SektorCT от Январь 28, 2023, 22:47



Название: Доступ к сигналу из другого потока
Отправлено: SektorCT от Январь 28, 2023, 22:47
Всем привет.
У меня класс который обращается к gui работает в отдельном потоке, и вроде нормально работало когда обращался к слотам.
Но мне теперь потребовалось реакцию на сигнал из С++.
В нужный qml добавил Connections { target: eventHandler; function onSignalAlertUserExists() {} } и вызвал сигнал.
И получаю теперь ошибку
QQmlEngine: Illegal attempt to connect to EventHandler(0x55.......) that is in a different thread than the QML engine QQmlApplicationEngine(0x7ff.........
Подскажите пожалуйста. С потоками я еще не идеально разбираюсь.
Спасибо.


Название: Re: Доступ к сигналу из другого потока
Отправлено: SektorCT от Январь 31, 2023, 09:50
Никто такой ошибки не видел?


Название: Re: Доступ к сигналу из другого потока
Отправлено: kambala от Январь 31, 2023, 10:39
решение лежит в первой же (или второй) ссылке в гугле:

You need to build a c++ model that lives in the main thread that is exposed to qml. Inside this model you can connect to signals emitted by your threads via a queuedconnection and link them to the models' own signals. Also you should make sure that when you read data from an object owned by another thread, everything is properly mutexed or you will be reading garbage.


Название: Re: Доступ к сигналу из другого потока
Отправлено: SektorCT от Январь 31, 2023, 16:11
решение лежит в первой же (или второй) ссылке в гугле:

Это в гугле не смог найти, искал несколько дней. По сути я понимаю что проблема в разных потоках. Но вот почему это приосходит если я из GUI обращаюсь к слотам то все работает а когда сигнал то получаю ошибку.

Код:
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
   
    ThreadsManagement management; // тут у меня классы буферов и eventHandler(для работы с GUI) и потоки для них
    QQmlApplicationEngine engine;
   
    engine.rootContext()->setContextProperty("eventHandler", management.getEventHandler());

    engine.addImportPath("qrc:/");
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

Могли бы что-то посоветовать?
Спасибо.


Название: Re: Доступ к сигналу из другого потока
Отправлено: kambala от Январь 31, 2023, 17:22
eventHandler живет в главном потоке, насколько я понимаю, потому проблемы из гуи нет.

в ответе же написано: надо создать свою С++ обертку, которая будет перенаправлять сигналы из других потоков в гуи, при этом соединение надо делать с типом queuedconnection (тип AutoConnection, который по умолчанию, может не сработать, т.к. смотрит на принадлежность объекта потоку лишь в момент вызова connect, насколько я помню). То есть в setContextProperty ты будешь передавать вот эту обертку (либо как замена eventHandler либо в дополнение к нему, тут сам смотри как тебе лучше).