Может ли кто-нибудь просто объяснить шаблон "сигналов и слотов"?
Что такое сигналы и слоты?
Ответ 1
Сигналы и слоты - это способ развязки отправителя (сигнала) и ноль или более приемников (слотов). Позвольте сказать вам систему, в которой есть события, которые вы хотите сделать доступными для любой другой части системы, заинтересованной в этих событиях. Вместо жесткой проводки кода, который генерирует событие для кода, который хочет знать об этих событиях, вы должны использовать шаблон сигналов и слотов.
Когда отправитель сигнализирует о событии (обычно, вызывая функцию, связанную с этим событием/сигналом), все получатели для этого события автоматически вызываются. Это позволяет подключать и отключать приемники по мере необходимости в течение всего срока службы программы.
Поскольку этот вопрос был помечен С++, вот ссылка на библиотеку Boost.Signals, которая имеет гораздо более подробное объяснение.
Ответ 2
Я думаю, что лучше всего описывать сигналы и слоты, когда вы смотрите на них как на возможное транспортное средство для шаблон наблюдателя или шаблон публикации/подписчика. Существует один signal
, например buttonPressed(IdType)
на стороне издателя. Всякий раз, когда нажимается кнопка, вызывается все слоты, которые подключены к этому сигналу. Слоты находятся на стороне подписчика. Слот может быть, например, sendMail(IdType)
.
Наряду с нажатием кнопки "событие" слот будет знать, какая кнопка была нажата, так как идентификатор был бы передан. IdType
представляет тип данных, отправленных по соединению между издателем и подписчиком. Операция, возможная для Абонента, будет connect(signal, slot)
, которая могла бы соединить buttonPressed(IdType)
с sendMail(IdType)
, так что, если кнопка нажата, вызывается этот конкретный слот.
Хорошо, что абонент (сторона слота) не нуждается в деталях сигнала. Ему просто нужно подключиться. Таким образом, здесь мы имеем много свободного сцепления. Вы можете изменить реализацию кнопок, но интерфейс для слотов все равно будет таким же.
Посмотрите Qt Signals/Slots или Повысить сигналы для получения дополнительной информации.
Ответ 3
Представьте, что в вашем приложении есть графический интерфейс. В большинстве случаев поток управления не будет очень линейным, т.е. Вместо четкой последовательности действий у вас будет пользователь, который взаимодействует с графическим интерфейсом (например, кнопки, меню и т.д.).
Это, по существу, модель, управляемая событиями, которая может быть реализована довольно хорошо с помощью шаблона сигналов и слотов. сигналы - это события, которые генерируются объектами (думают компоненты GUI), а слоты - приемники этих событий.
Вот пример: представьте, что у вас есть флажок, представленный как объект на вашем языке программирования. С этим флажком может произойти несколько вещей: его можно переключить, что, в свою очередь, также означает, что он либо установлен, либо отменен. Это сигналы, которые он может испускать. Назовем их checkboxToggled, checkboxSet и checkboxUnset. Как вы видите, в этом примере флажок всегда будет вызывать сигнал checkboxToggled при переключении, но также точно один из двух других сигналов, в зависимости от того, как изменяется состояние.
Теперь представьте, что у вас есть другие объекты, а именно метка, которая для этого примера всегда существует как объект, но может "появляться" и "исчезать" и системный звуковой сигнал (также представленный объектом), который может просто звуковой сигнал. Это слоты, которые есть у этих объектов. Мы будем называть их "messageAppear", "messageDisappear" и "beep".
Предположим, что вы хотите, чтобы системный звуковой сигнал подавал звуковой сигнал каждый раз, когда галочка переключается, а ярлык появляется или исчезает в зависимости от того, установлен ли флажок или снят флажок.
Таким образом, вы подключаете следующие сигналы к следующим слотам (сигналы слева, слоты справа):
checkboxToggled -> beep
checkboxSet -> messageAppear
checkboxUnset -> messageDisappear
В основном это.
сигналы и слоты также могут иметь аргументы. Например, используя ползунок, который устанавливает числовое значение, вы хотите отправить измененное значение вместе с испускаемым сигналом, как только пользователь переместит ползунок: sliderChanged (int).
Конечно, чтобы на самом деле сделать что-то полезное, вы должны написать некоторые собственные классы, которые будут содержать некоторые собственные сигналы и слоты. Это делается довольно легко и, используя эти собственные сигналы и слоты, у вас есть хороший способ взаимодействия с графическим интерфейсом или другими частями вашего кода в режиме, управляемом событиями.
Имейте в виду, что сигналы и слоты часто симметричны в том смысле, что часто может быть сигнал, соответствующий слоту. Например, флажок может выдавать сигнал при переключении, но он также может содержать слот, который переключает флажок. Было бы легко реализовать отдельные флажки, которые всегда устанавливаются противоположно друг другу.
Ответ 4
Я предполагаю, что вы говорите о сигналах и слотах QT.
Это очень просто.
Экземпляр класса может запускать сигнал, а другой экземпляр, возможно, другого класса может поймать этот сигнал в слоте. Это похоже на вызов функции только потому, что парню, который вызывает функцию, не нужно знать, кто хочет принять вызов.
Лучший пример для иллюстрации - пример.
Класс QPushButton имеет сигнал QPushButton:: clicked(). Этот сигнал запускается всякий раз, когда нажимается кнопка. Нажимать кнопку не нужно знать, кто заинтересован знать, что щелчок произошел. он просто запускает сигнал, и любой, кто заинтересован, может подключиться к нему.
QDialog, в который помещается кнопка, является интересным знать, когда была нажата кнопка. Он имеет слот MyDialog:: buttonClicked(). В MyDialog c'tor вам нужно подключить() сигнал кнопки() к диалоговому окну диалога щелчка(), чтобы слот вызывался при срабатывании сигнала.
Букет более продвинутых вещей:
- Аргументы, сигнал может иметь аргументы, и эти аргументы также могут быть переданы в слот.
- вызовы перекрестных потоков. Если вы создаете соединение с сигнальным слотом, которое должно быть поперечным, тогда QT автоматически буферизует сигналы и ставит их в нужную цепочку. Это происходит автоматически, например, когда поток GUI должен взаимодействовать с рабочим потоком.
Ответ 5
Лучший пример и объяснение, которое я нашел для сигналов и слотов, эта статья проекта кода.
Ответ 6
Существует общее недоразумение, что классы - существительные, такие как Личность, Собака, Велосипед и т.д. Тогда имеет смысл думать, что у человека (экземпляра) есть собака и велосипед.
Давайте начнем с того, какие объекты (предположительно). Объектами являются данные и процедуры. Что такое программы? Данные и процедуры. Предполагается, что объекты должны быть (относительно) "малыми" независимыми подпрограммами. Потому что программирование оооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооооеееееееееееееееееееееееееееееееееееееееееееееееееее Это не так, объекты - это "маленькие" независимые программы с "малым" API (общедоступные подпрограммы). Некоторые программисты даже не разбивают свой проект на подпрограммы и просто используют объекты, где данные и процедуры более подходят.
Теперь, предполагая, что мы согласны с тем, что объекты являются программами, мы можем согласиться с тем, что в большинстве случаев программам не нужно иметь копии других программ с аналогичным размером и сложностью (т.е. объект не является указателем на другой объект), ему могут потребоваться более мелкие программы для управления данными (например, структуры данных), но имхо не нужен другой объект.
Почему? Потому что объекты связи делают их зависимыми. Почему это плохо? Поскольку, когда объекты независимы, вы можете их протестировать, а также обещать другим программистам и клиентам, что объект (небольшая независимая программа) способен выполнять определенные задачи с высокой степенью уверенности. Вы также можете быть уверены, что он продолжает выполняться до тех пор, пока никаких изменений в этот объект не будет.
Итак, что такое слоты и сигналы? Если вы понимаете, что объекты похожи на программы, и они не должны идеально хранить копии или указатели на другие объекты, чем вам нужно, чтобы они могли общаться. Например, процессы, выполняемые на вашем компьютере, могут использовать сокеты, IP-адреса и порты для связи. Объекты могут использовать нечто очень похожее на RPC, называемое сигналами и слотами. Это структура данных, предназначенная как посредник между двумя более крупными объектами, которые хранят подпрограммы объекта (slots
) и позволяют другим объектам вызывать (signal
) эти подпрограммы (slots
) с подходящими параметрами, не зная ничего об этих других объекты, отличные от тех параметров, которые им требуются.
Таким образом, базовая структура - это множества (возможно, массивы) (возможно) строго типизированных указателей процедур, которые другие объекты могут вызывать с подходящими параметрами без указателя на эти объекты. Абонентам нужен только доступ к сигнальному объекту (который не содержит деталей реализации), который определяет ожидаемые параметры.
Это также гибко, потому что это позволяет использовать некоторые специальные варианты использования, такие как слоты, которые только реагируют на сигнал один раз, несколько слотов для одного сигнала и другие подобные варианты использования, такие как debouncing.