Сигнали і слоти в 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 ++, є одним з рішень для розробки більш незалежних графічних користувацьких інтерфейсів. За цю репутацію відповідають, насамперед, такі інструменти, як сигнали і слоти, реалізовані в останніх версіях, які не тільки оптимізує робочий процес в цілому, але і полегшують співробітництво між дизайнерами і програмістами.