У меня проблемы с сигналами Qt.
Я не понимаю как DirectConnection
а также QueuedConnection
работает?
Я был бы благодарен, если кто-то объяснит, когда использовать какой из них (пример кода будет оценен).
Вы не увидите большой разницы, если не будете работать с объектами, имеющими различную привязку к потоку. Допустим, у вас есть QObjects A
а также B
и они оба привязаны к разным темам. A
имеет сигнал под названием somethingChanged()
а также B
имеет слот под названием handleChange()
,
Если вы используете прямое соединение
connect( A, SIGNAL(somethingChanged()), B, SLOT(handleChange()), Qt::DirectConnection );
метод handleChange()
на самом деле будет работать в A
это нить. По сути, как будто излучение сигнала вызывает метод слота «напрямую». Если B::handleChange()
не является поточно-ориентированным, это может вызвать некоторые (трудно найти) ошибки. По крайней мере, вы упускаете преимущества дополнительной ветки.
Если вы измените метод подключения на Qt::QueuedConnection
(или, в этом случае, пусть Qt решит, какой метод использовать), все становится более интересным. Если предположить, B
поток запускает цикл обработки событий, издающий сигнал, B
Цикл событий. Цикл событий ставит в очередь событие и в конечном итоге вызывает метод слота всякий раз, когда управление возвращается к нему (это цикл события). Это позволяет довольно легко взаимодействовать между / между потоками в Qt (опять же, предполагая, что ваши потоки запускают свои собственные локальные циклы событий). Вам не нужно беспокоиться о блокировках и т. Д., Поскольку цикл обработки событий сериализует вызовы слотов.
Примечание: Если вы не знаете, как изменить сродство потока QObject, посмотрите на QObject::moveToThread
, Это должно начать вас.
редактировать
Я должен уточнить мое вступительное предложение. Это имеет значение, если вы уточнить соединение в очереди — даже для двух объектов в одном потоке. Событие по-прежнему отправляется в цикл событий потока. Таким образом, вызов метода все еще асинхронный, что означает, что он может быть отложен непредсказуемым образом (в зависимости от любых других событий, которые цикл может потребоваться обработать). Однако, если вы не укажете метод соединения, прямой метод автоматически используется для соединений между объектами в одном потоке (по крайней мере, в Qt 4.8).
в дополнение к ответу Джейкоба Роббинса:
утверждение «Вы не увидите большой разницы, если не будете работать с объектами, имеющими различную привязку к потоку», неправильно;
передача сигнала на прямое соединение в том же потоке немедленно выполнит слот, как простой вызов функции.
передача сигнала подключению в очереди в том же потоке поместит вызов в цикл событий потока, таким образом, выполнение будет всегда случиться с задержкой.
Ответ Джейкоба потрясающий. Я просто хотел бы добавить сравнительный пример во встроенное программирование.
Исходя из встроенного фона RTOS / ISR, было полезно увидеть сходства в DirectConnection Qt с Preemptive поведением ISR и QueuedConnection Qt для сообщений в очереди в RTOS между задачами.
Примечание: Исходя из встроенного фона, мне трудно не определить поведение в программировании. Я никогда не оставляю аргумент за Авто, но это только личное мнение. Я предпочитаю, чтобы все было написано в явном виде, и да, это иногда бывает трудно!