вторник, 31 января 2012 г.

Qt Сигналы и слоты, что и как?

Главной особенностью библиотеки Qt является технология сигналов и слотов (Signals and slots). Не могу вам сказать что она чем-то значительно лучше других подходов, но мне эта штука нравится :)



В чем же суть. В вашем коде любой объект (кнопка, класс, виджет, форма, таймер и т. д.) может испускать сигналы. Когда и почему испускать сигналы решаете вы, ну или иногда (для классов из библиотеки) эти сигналы уже определены. Посмотрим, какие же классы предопределены скажем для QTextEdit (поле для ввода текста). Для этого открываем справку (красным цветом), проверяем, чтобы у нас отображалась справка по указателю (оранжевым цветом) и ищем QTextEdit. Листаем открывшуюся справку до поля Signals (зеленым цветом).


Как вы можете видеть, у QTextEdit есть 7 собственных сигналов и по одному сигналу от QWidget и от QObject.
Например, сигнал void cursorPositionChanged() испускается каждый раз, когда внутри текстового поля меняется позиция курсора, а сигнал textChanged() испускается при изменении текста внутри текстового поля.
Что же делать с сигналами. Как и сигналы от девушек, эти сигналы надо ловить :)))
В нашем случае сигналы ловятся слотами. Для того, чтобы слот "поймал" сигнал, их надо подключить друг к другу. делается это функцией QObject::connect().

Ради интереса посмотрим, какие же слоты есть у нашего QTextEdit.


Рассмотрим первый слот void append (const QString & text). Мы можем подключить к этому слоту какой-то сигнал, который также будет передавать в качестве параметра строку QString, и тогда к тексту в QTextEdit будет присоединяться переданная нами строка.

Слот void clear() отчищает текст в QTextEdit.

Простой пример кода:


    QTextEdit text;

    connect(text, SIGNAL(textChanged()), text, SLOT(clear()));


Логика простая. Мы создали объект text класса QTextEdit. В данном случае нам не надо писать  QObject (знатоки догадаются, а новеньким вдаваться пока не стоит).
В данном случае формат функции connect следующий:

connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoConnection )т.е. в функцию нам необходимо передать:
*sender - указатель на объект-отправитель (в нашем случае это text)
*signal - какой сигнал мы подключаем
*receiver - указатель на объект-получатель (в нашем случае это тот же самый text)
type - способ подключение (лично я им ещё не разу не пользовался )

т.е. мы подлючаем сигнал textChanged() к сигналу clear(), и если человек пытается ввести в наше текстовое поле какой-то текст, поле автоматически отчищается.
Проще говоря мы издеваемся над пользователем :))






6 комментариев:

  1. А вообще, если Вы впервые сталкиваетесь с механизмом сигналов и слотов, приведу Вам тогда ассоциативный ряд.
    Сигнал - это мужчина, который постоянно ищет и пробует самых различных женщин, а слот - это женщина, которая постоянно выбирает нужного ей мужчину, ну а метод connect - это брак, связывающий сигнал со слотом во веки вечные, также как и мужчину с женщиной.
    Однако здесь нам представлен пример мусульманской семьи с демократическим налетом европейской толерантности, где возможно многоженство и многомужство.

    ОтветитьУдалить
  2. А когда один сигнал к нескольким слотам? Или несколько сигналов к одному слоту? Многоженство? :)

    ОтветитьУдалить
  3. Сергей а могли бы вы написать статью про QSignalMapper, а то вот вроде и разобрался, но вот не работает, видимо что то недопонял. А вы всё доступно и наглядно расписывайте. Заранее спасибо.

    ОтветитьУдалить
  4. Постараюсь завтра описать.

    ОтветитьУдалить
  5. я вот не могу понять в чем выгода в этой системе, весь вся разница в том что при сигналах и слотах ты "вызываешь функцию" = "Конектиш" в конструкторе обьекта, а без этой системы сигналов и слотов ты просто вызываешь функцию там где нужно ниже по коду...в функциях объекта. Экономии кода никакой, зато все неявно и можно забыть где ты что связывал

    ОтветитьУдалить