Evgenii Legotckoi
9 ноября 2017 г. 13:22

Qt/C++ - Урок 073. Сигналы и слоты. Подключение слотов к перегруженным сигналам в рамках синтаксиса Qt5

Довольно частой проблемой при работе с сигналами с слотами в Qt5 по моим наблюдениям за вопросами на форуме является подключение слотов в рамках синтаксиса на указателях к сигналам имеющим перегрузку сигнатуры. Тоже самое касается и слотов, которые имеют перегрузку.

Возьмём тестовый класс, который имеет перегруженные сигналы.

  1. #include <QObject>
  2.  
  3. class TestClass : public QObject
  4. {
  5. Q_OBJECT
  6. public:
  7. explicit TestClass(QObject *parent = nullptr);
  8.  
  9. signals:
  10. void testSignal(int arg1);
  11. void testSignal(int arg1, int arg2);
  12. };

Здесь имеется сигнал, с перегрузкой сигнатуры. Подключаться данный сигнал также будет к слотам, которые объявлены в классе Widget , и которые также имеют перегрузку сигнатуры.


  1. #include <QWidget>
  2. #include "testclass.h"
  3.  
  4. namespace Ui {
  5. class Widget;
  6. }
  7.  
  8. class Widget : public QWidget
  9. {
  10. Q_OBJECT
  11.  
  12. public:
  13. explicit Widget(QWidget *parent = 0);
  14. ~Widget();
  15.  
  16. private slots:
  17. void onTestSlot(int arg1);
  18. void onTestSlot(int arg1, int arg2);
  19.  
  20. private:
  21. Ui::Widget *ui;
  22. TestClass* m_testClass;
  23. };

Как было в Qt4

В рамках Qt4 всё решалось довольно просто, указанием сигнатуры сигнала и слота в макросах SIGNAL и SLOT.

  1. connect(m_testClass, SIGNAL(testSignal(int,int)), this, SLOT(onTestSlot(int,int)));
  2. connect(m_testClass, SIGNAL(testSignal(int)), this, SLOT(onTestSlot(int)));

Как стало в Qt5

А вот в Qt5 при записи в новом синтаксисе сигналов и слотов имеются некоторые проблемы. Поскольку потребуется делать static_cast сигнатуры метода.

  1. connect(m_testClass, static_cast<void(TestClass::*)(int)>(&TestClass::testSignal),
  2. this, static_cast<void(Widget::*)(int)>(&Widget::onTestSlot));
  3. connect(m_testClass, static_cast<void(TestClass::*)(int, int)>(&TestClass::testSignal),
  4. this, static_cast<void(Widget::*)(int, int)>(&Widget::onTestSlot));

К слову говоря, новый синтаксис также позволяет подключать сигналы к слотам с меньшей сигнатурой, как это было в Qt4.

  1. connect(m_testClass, static_cast<void(TestClass::*)(int, int)>(&TestClass::testSignal),
  2. this, static_cast<void(Widget::*)(int)>(&Widget::onTestSlot));

Плюсы нового синтаксиса

А теперь камень преткновения. Зачем использовать новый синтаксис сигналов и слотов? Этот вопрос до сих пор периодически слышу. Особенно, когда люди видят такие страшные касты сигнатур.

Поэтому перечислю потенциальные плюсы:

  1. Возможность отслеживания ошибок в подключении сигналов и слотов ещё на этапе компиляции, а не в рантайме
  2. Уменьшение затрат времени компиляции за счёт исключения макросов из кода
  3. Возможность подключения лямбда функций, это довольно важная плюшка
  4. Ограждаем себя от ошибок, когда пытаемся подключиться извне к приватному слоту. Да!! Да!! Макросы SIGNAL и SLOT игнорируют уровни доступа методов, нарушая ООП.

В общем-то для меня уже этого достаточно, а для Вас?

Вам это нравится? Поделитесь в социальных сетях!

АК
  • 9 ноября 2017 г. 15:50

Отличная необходимая статья.

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь