Как встроить Qt в другое приложение (неблокирующим способом) - PullRequest
0 голосов
/ 04 июля 2019

Я использую C ++ API для 3D-рендеринга и хочу использовать Qt для отображения GUI поверх него.

Мой API-интерфейс рендеринга работает в потоке приложения main () , какQt хочет.

Сначала я попытался запустить Qt в своем собственном std :: thread, и он прекрасно работал - и я понятия не имею, что означает документ Qt с

Как уже упоминалоськаждая программа имеет один поток при запуске.Этот поток называется «основным потоком» (также известным как «поток GUI» в приложениях Qt).Графический интерфейс Qt должен работать в этом потоке https://doc.qt.io/qt-5/thread-basics.html

Это либо неверно, либо плохо написано ...

Мой рабочий std :: thread выглядит примерно так:

int SomeClass::qt_app_worker(size_t width, size_t height, const std::string& title, const std::string& contents) {
    int argc = 0;
    QApplication app(argc, NULL);
    // QDialog here
    return app.exec();
}

Проблема в том, что я ничего не могу сделать с этим приложением Qt, потому что если я попытаюсь создать, скажем, другой QDialog из потока main (), Qt будет жаловаться, что я могу сделать это только из потока, владеющего моимQApplication (qt_app_worker).

Так что я либо навсегда заблокирован из потока qt_app_worker, либо мне нужно реализовать собственную очередь сообщений для ВСЕГО, связанного с Qt.

Я набросал ее с помощьюпроизводный класс QApplication с использованием startTimer () и последующей обработкой пользовательских сообщений в timerEvent (...), но это слишком много хлопот.

Я просто не понимаю, почему Qt не позволяет пользователю запускать его вотдельная тема, надеюсь, я просто что-то упустил.

1 Ответ

0 голосов
/ 04 июля 2019

Существует (как минимум) два встроенных поточно-безопасных способа связи с потоком GUI (который обычно является «основным потоком» приложения Qt, поэтому его часто называют основным потоком, и для точки Qt).с точки зрения это).

  • Вы можете публиковать события (включая ваши собственные пользовательские подклассы событий) в ветке, используя QCoreApplication::postEvent.
  • Вы можете вызватьметоды объектов в другом потоке, при условии, что вы делаете это с типом соединения Qt::QueuedConnection или Qt::BlockingQueuedConnection, используя QMetaObject::invokeMethod (и его различные перегрузки).

Связь с другимКстати, от Qt до вашего собственного основного потока, это может произойти несколькими способами.Я считаю, что использование Qt::BlockingQueuedConnection также позволяет получить возвращаемое значение, но вы, вероятно, не хотите эту блокировку .... Поэтому вы можете просто использовать любой из обычных методов связи между потоками, не ограниченных Qt, например просто атомарныйили переменные, защищенные мьютексом, которые устанавливаются из Qt, и ваши потоки опрашивают или читают иначе, когда это уместно (например, в начале каждого кадра).Или создайте простую очередь сообщений, если вы хотите отслеживать каждое изменение, а не только состояние в начале кадра или что-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...