LINUX.ORG.RU

Qt Взаимодействие GUI с Backend

 ,


0

4

Здравствуйте.

Имеется приложение. GUI крутится в одном потоке, бэкенд в другом. Каким способом будет лучше всего наладить взаимодействие между ними?

Я думал о способе, что допустим при нажатии на кнопку на форме Event записывается в глобальную очередь, а бэкенд видит, что там что-то появилось, берёт из очереди Event, как-то его обрабатывает, смотрит, от какого виджета оно пришло и что за событие, и на основании этой инфы уже что-то делает. Если нужно на форме что-то поменять, то мы бекенд помещает в другую очередь действие, что там надо сделать. И после этого поток GUI видит, что для него что-то есть, читает значение из очереди, и что-то уже делает.

Но такое чувство, что это страшный велосипед просто. Кто что посоветует?

У меня такая ж хрень. Бекенд крутится в своих потоках и шлет сигналы, на которые подписано приложение на Qt. фронтенд, в свою голову, может слать события бекенду или дергать его вызовы через внешний интерфейс, да.

anonymous ()

Ты вот сейчас изобрёл сигналы/слоты.

Только без сахарку.

Как говорится rtfm для начала, например про QEventLoop и про QApplication.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

а если бекенд ничего про Qt не знает? =))

anonymous ()
Ответ на: комментарий от pon4ik

да про сигналы\слоты вроде знаю. Не могу сказать, что с Qt до этого много работал. Сигналы между потоками передаются?

zamazan4ik ★★ ()
Ответ на: комментарий от anonymous

а если бекенд ничего про Qt не знает

То, это прекрасно. Ну в таком бэкэнде либо уже есть очередь сообщений, либо да её надо сделать отдельно.

Однако речь шла про Qt и по дефолту я подразумеваю что используется Qt :)

pon4ik ★★★★★ ()

Сигналы-слоты через кутешную стандартную очередь сообщений в QThread

trex6 ★★★★★ ()
Ответ на: комментарий от zamazan4ik

Сигналы обрабатываются в EventLoop, который есть в кадом QThread. При коннекте не забывай указывать соответствующий тип связи (5-й параметр в коннекте). Не забудь прочитать статью, как правильно готовить QThread и после этого бекенд объекты переносить в соответствующий тред.

trex6 ★★★★★ ()
Ответ на: комментарий от trex6

При коннекте не забывай указывать соответствующий тип связи (5-й параметр в коннекте)

Там по умолчанию стоит Qt::AutoConnect, так что можно ничего не указывать:

If the signal is emitted from a different thread than the receiving object, the signal is queued, behaving as Qt::QueuedConnection. Otherwise, the slot is invoked directly, behaving as Qt::DirectConnection. The type of connection is determined when the signal is emitted

XMs ★★★★★ ()
Ответ на: комментарий от XMs

Для этого объекты должны быть размещены в разных тредах _до_ коннекта. В целом может сработать, но я предпочитаю указывать явно.
К тому же такое указание полезно для читающих код.

trex6 ★★★★★ ()
Ответ на: комментарий от trex6

Для этого объекты должны быть размещены в разных тредах _до_ коннекта
The type of connection is determined when the signal is emitted

XMs ★★★★★ ()

Сигналы-слоты Qt отлично работают меж потоками.

grondek ()
QThread my_thread;
my_class backend; // my_class - от QObject
...
backend.moveToThread(&my_thread);
my_thread.start();
...

И дальше соединяешь frontend при помощи сигнал-слотов с backend и получаешь потокобезопасное взаимодействие без усилий, если используешь Qt-шные классы и контейнеры.

Что я понимаю под «без усилий» - отсутствие мьютексов и типичных рисков, потому что в этом сценарии Qt берет всё на себя. Поправьте если ошибаюсь.

Советую обратить внимание на то что я предложил. Я очень много лет парился с потоками в Qt, пока не осознал этот простой путь, который заложили разработчики Qt, но наверное недостаточно хорошо пояснили...

P.S. Почитал, выше советуют ровно то же что и я.

I-Love-Microsoft ★★★★★ ()
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.