Сигналы и слоты в Qt: установка, особенности работы, создание
Сигнал представляет собой сообщение, посылаемое от объекта при входе в событие. Со своей стороны, слот является общей функцией, связанной с сигналом, который должен выполняться, когда он принимается. Можно связать сигнал с несколькими слотами, чтобы в результате одного события выполнялось несколько функций. Кроме того, эта концепция позволяет связывать несколько сигналов в одном слоте, и в этом случае одна и та же функция будет выполняться с несколькими событиями.
Qt сигналы и слоты помогают включить ориентированную на событие функцию в графические пользовательские интерфейсы приложений. Пользователям не придется тратить время на создание ссылок на слоты сигналов один за другим. Так как многие классы инфраструктуры предоставляют к ним различный доступ к предопределенным Qt сигналам и слотам.
Сигналы и слоты: отличительные особенности
Сигналы и слоты сделали Qt увлекательным и инновационным инструментом. Это метод, в которым «один объект» гарантирует, что когда «что-то произошло», то «другой объект» реагирует на случившееся. Это можно выразить в псевдокоде.
Четыре фразы в кавычках в примере являются аргументами вызова функции в псевдокоде. Одним из типичных способов написания оператора connect выполняется выравниванием аргументов. Это имеет преимущество по сравнению с типичным механизмом, используемым в стандартном C или C ++, таким как обратные вызовы с указателями на функции, заключенными в std :: function.
Если объект-отправитель уничтожен, он не может излучать какой-либо сигнал, поскольку является функцией-членом своего класса. Но для того, чтобы отправитель вызвал получателя, ему нужно указать на него. Пользователю не нужно будет беспокоиться о том, что получатель будет уничтожен и станет недействительным, это делается библиотекой автоматически. Такая схема функционирования делает по умолчанию Qt сигналы и слоты безопасными.
Новый механизм связи
Qt предоставляет некоторые языковые дополнения через макросы, которые обрабатываются инструментом генератора кода Meta-object Compiler (MOC). Это приводит к более продвинутой поддержке самоанализа со специальными механизмами в классах в Qt. К ним относится подход сигналов и слотов объекта связи.
Соединение устанавливается с помощью вызова QObject :: connect (), позволяющего подключать только те, которые имеют совместимые аргументы, обеспечивая таким образом безопасность. Объекты не знают о сигналах, на которые подписываются их слоты, тем самым сохраняя слабую связь объектов. Пример того, как «нормальный» класс C ++ может быть расширен для поддержки сигналов и слотов и как это поведение реализовано, можно увидеть ниже.
Эти специальные макросы выбираются инструментом генератора кода MOC, который генерирует соответствующие классы и функции, реализующие все механизмы, специфичные для Qt. Они должны быть выполнены пользователем приложения. Ниже приведена возможная форма слота Counter :: setValue ().
Можно увидеть оператор emit, для ожидания Qt сигнала valueChanged () с данными в качестве аргумента, когда назначается новое значение.
Обновленные функциональные возможности
Начиная с Qt 5.0, существует новая перегрузка QObject::connect, которая поддерживает передачу данных через сигналы Qt в качестве второго и четвертого аргументов указателя на функцию, указывающую ту, которую нужно вызывать.
Новый синтаксис позволяет вызывать не только функцию-член, объявленную, как слот в заголовке с public slots, но и любую функцию. Есть еще один вариант использования, когда нужно объявить функции, как слоты, чтобы сделать их пригодными для использования любой другой, которая реализуется во время выполнения. Это может быть, например, QML.
Можно подключиться к любой «вызываемой» функции, которая может быть автономной, лямбда-функцией или членом объекта, который не является производным QObject.
При подключении к лямбде есть объект-получатель, сама лямбда, но нет подписи, которую можно указать, поскольку это оператор вызова функции. И когда есть отдельно стоящая функция и подпись, третий и четвертый аргументы первых двух вызовов объединяются.
Симметрия и безопасность
Начиная с Qt 5.2, можно получить лучшую из обеих реализаций и хорошо сбалансированного оператора соединения с двумя объектами и двумя функциями. В этой версии Qt была добавлена дополнительная перегрузка и теперь есть возможность передать, как третий аргумент «объект контекста», который служит для автоматического разрыва соединения и гарантирует отсутствие проблем.
В Qt есть служебные классы, которые QObject автоматически обрабатывают, например, QScopedPointer QObjectCleanupHandler. Если у пользователя есть какая-то часть приложения, использующая классы Qt, но нет тесно связанного с этим пользовательского интерфейса, он сможет найти способ использовать их в качестве членов класса, не основанного на QObject.
Комплексная библиотека
У Qt есть набор библиотек под названием QtCore, охватывающий, набор основных функций:
- Среда приложения с циклами событий и системой событий.
- Система графического интерфейса, которая является одним из самых сильных активов.
- Qt шаблонные контейнеры, такие как списки, очереди, вектор и карты. Они обеспечивают прекрасную альтернативу контейнерам STL, предоставляя механизмы для итерации в стиле Java или STL и преобразования в аналоги STL.
- Классы управления ресурсами.
- Система представления моделей для разделения данных и их представлений на основе набора абстрактных классов.
- Фреймворк для потоков Qt сигналов слотов.
- Обработка строк и регулярные выражения.
- Функциональные возможности ОС, такие как обработка файлов, печать, сетевые возможности и системные настройки.
Кроме того, есть несколько других пакетов, большинство из которых являются зрелыми и многофункциональными в областях: обработки XML, мультимедийных возможностей, поддержки баз данных SQL, модульного тестирования, OpenGL, интеграцию WebKit, библиотек, инструментов интернационализации, манипуляции SVG, связи по шине D-Bus, элементов управления ActiveX и других.
Управление ресурсами
Два механизма управления ресурсами в Qt - это иерархия владения и неявного совместного использования. Иерархия владения состоит из дерева объектов, которое обрабатывает уничтожение потомков. Всякий раз, когда новый объект на основе QObject создается в куче, используя new, ему назначают родительский объект QObject, что в итоге приводит к созданию иерархического дерева объектов. Когда объект уничтожается в дереве, все его потомки также уничтожаются.
Неявное совместное использование относится к внутреннему механизму, в основном используемому для контейнеров Qt и больших объектов. Он реализует подход копирования при записи, то есть он передает указатель на структуру данных только при каждом назначении и копирует полную структуру данных только в случае операции записи. Это гарантирует, что ненужные копии не создаются из больших структур данных, что повышает производительность.
Создание собственных сигналов и слотов
Пользователям не нужно полагаться исключительно на сигналы, предоставляемые виджетами, можно создать Qt сигнал с использованием класса Signal:
• from PySide.QtCore import Signal;
• tapped = Signal().
Затем, когда условия для объекта, к которому подключаются, удовлетворяются, вызывают метод сигнала, и он излучается, вызывая любые Qt слоты, к которым он подключен: thing.tapped.emit().
Это хорошо по двум причинам, во-первых, он позволяет пользователям объектов взаимодействовать с объектами знакомыми способами. Во-вторых, он позволяет более гибко использовать их, оставляя эффекты определения действий над ними для использующего кода.
Простой пример генерации
Можно определить простой PunchingBag класс, который делает только одно, когда он «punch» вызывается, то генерирует punched сигнал.
В Punching Bag унаследован признак от QObject так, что может излучать сигналы, у него есть вызванный сигнал punched, который не несет никаких данных и punch метод, который делает только излучение punched сигнала Qt. Чтобы сделать Punching Bag полезным, нужно подключить его punched сигнал к слоту. Определяют простую функцию, которая печатает на консоли, создают экземпляр Punching Bag и подключают его punched сигнал к слоту.
Если поместите все это в скрипт и запустите его, он обеспечит реализацию реакции на перфорацию использующего кода.
Одна из самых интересных вещей, которые можно сделать при использовании Qt creator - создание сигналов, чтобы заставить их переносить данные. Например, можно заставить сигнал нести целое число, таким образом:
- 1 updated = Signal(int);
- 1 updated = Signal(str).
Тип данных может быть любым именем типа Python или строкой, идентифицирующей тип данных C ++.
Круг отправки PySide/PyQt
Circle унаследован от QObject так, что может излучать сигналы. Сигналы создаются с подписью слота, к которому они будут подключены. Один и тот же сигнал может излучаться в нескольких местах.
Теперь определяют некоторые слоты, которые можно подключить к сигналам Круга. Для этого существуют сигналы, которые переносят данные. Чтобы слот принимал данные от сигнала, его определяют с той же сигнатурой, что и у сигнала.
Код очень простой и интуитивно понятный. Далее создают экземпляр Circle, подключив сигналы к слотам, переместим и изменим его размер.
Когда запускается полученный скрипт, вывод должен быть:
- Circle was moved to (6, 5).
- Circle was resized to radius 5.
Преимущества платформы
Qt превратилась в платформу для разработки, как для настольных компьютеров, так и для мобильных устройств, в диапазоне настроек от личного использования до промышленного или встроенного программного обеспечения.
Существует набор инструментов, который предоставляется вместе с Qt, используя процесс разработки. К нему относятся следующие:
- Qt creator сигналы и слоты, простая IDE, которая поддерживает различные конфигурации сборки и имеет сильную поддержку для отладки кода с поддержкой Qt,
- Qt Designer, графический редактор GUI, который также может быть интегрирован в другие IDE,
- Qt Linguist, менеджер по интернационализированным текстам, который легко обрабатывается в Qt.
- Qt Assistant, приложение справки, которое включает документацию по Qt API, но также может быть интегрировано в собственные приложения для предоставления справочной системы.
Система используют точки останова или qDebug, чтобы проверить, что сигнал и код слота определенно достигнуты:
- оператор connect;
- код, где подается сигнал;
- код слота.
Секреты и уловки
Можно подключить сигнал непосредственно к сигналу другого объекта. Что применяют, например, для пересылки сигналов.
Ниже приведены некоторые рекомендации по устранению неисправностей сигналов и слотов в библиотеке Qt C ++:
- Проверяют предупреждения компилятора о несуществующих сигналах или слотах.
- Убеждаются, что типы параметров сигнала и слота являются точными и, при необходимости, соответствуют друг другу.
- Убеждаются, что не добавлено имя в аргумент сигнала или слота, например, используются textChanged (const QString &), а не textChanged (const QString & text).
- Проверяют правильность аргументов и синтаксиса подключения.
- Проверяют скобки, убеждаются, что SIGNAL и SLOT написаны с большой буквы и что отправитель и получатель являются объектами, а не именами классов.
- Убеждаются, что сигнал срабатывает, как и ожидалось. Можно сделать это с помощью следующего кода: connect(this, SIGNAL(Signal()), qApp, SLOT(aboutQt())).
- Убеждаются, что слоты правильно объявлены в соответствующих разделах public/protected/private slots объявления класса.
- Убеждаются, что использованы частные слоты:. Проверяют двоеточие, то есть частные слоты: и не частные слоты.
- При использовании пользовательских сигналов, убеждаются, что они объявлены правильно, с типом возврата «void», в разделе открытых/ защищенных/частных сигналов объявления класса.
Qt - это традиционная структура, которая постоянно адаптируется к требованиям современных пользовательских графических интерфейсов. Неудивительно, что эта подборка инструментов, написанных на C ++, является одним из решений для разработки более независимых графических пользовательских интерфейсов. За эту репутацию отвечают, прежде всего, такие инструменты, как сигналы и слоты, реализованные в самых последних версиях, которые не только оптимизируют рабочий процесс в целом, но и облегчают сотрудничество между дизайнерами и программистами.