частные / общедоступные сигналы qt

Могут ли сигналы Qt быть общедоступными или частными? Могу ли я создавать внутренние сигналы, которые видны только внутри класса?

Обновление: у меня есть класс с некоторыми внутренними сигналами. Как я могу сделать эти сигналы невидимыми для других классов (инкапсуляция и скрытие информации)?


person anton    schedule 26.01.2010    source источник
comment
В этом случае используйте шаблон PIMPL.   -  person Th. Thielemann    schedule 21.10.2020


Ответы (7)


Нет. Сигналы не могут быть общедоступными или частными. Сигналы Qt - это методы защищенного класса.

Ключевое слово "сигналы" определено в qobjectdefs.h (строка 69 как для Qt 4.6.1):

#   define signals protected

ОБНОВЛЕНИЕ: сигналы используются только protected до и включают все второстепенные версии Qt 4. Начиная с Qt 5.0 и далее они являются public. См. https://stackoverflow.com/a/19130831.

person Andrei Vlasyuk    schedule 27.01.2010
comment
Я считаю, что сигналы теперь считаются public см. Здесь stackoverflow.com/questions/19129133/ - person johnbakers; 02.10.2013
comment
Кажется, могут быть частные сигналы: doc.qt.io/qt-5/ qstate.html # finished - как они создаются? - person derM; 27.07.2017

Обычный способ, например видно в kdelibs, это:

Q_SIGNALS:
#ifndef Q_MOC_RUN
    private: // don't tell moc, doxygen or kdevelop, but those signals are in fact private
#endif

   void somePrivateSignal();

Это делает сигнал частным, то есть он может быть испущен только самим классом, но не его подклассами. Чтобы "private:" не отменял Q_SIGNALS (тогда moc не видел somePrivateSignal как сигнал), он находится внутри Q_MOC_RUN, который определяется только при запуске moc.

Изменить: Этот подход не работает для соединений нового стиля, представленных в Qt 5 (connect(a, &A::someSignal, b, &B::someSlot)), поскольку они требуют, чтобы сигнал был доступен.

person Frank Osterfeld    schedule 07.04.2011
comment
Нет, поскольку #define Q_SIGNALS защищен, private: не будет иметь никакого эффекта - person Frank Osterfeld; 10.01.2013
comment
Драт. Почему все в C ++ требует взлома? - person weberc2; 24.06.2013
comment
Этот подход не работает для соединений нового стиля, представленных в Qt 5 - зависит ... Если кто-то хочет только разрешить внутреннее соединение с сигналом (где тогда слот может испустить еще один, затем открытый сигнал), тогда это идеальный - за исключением того, что старый синтаксис все еще позволял подключиться к нему ... - person Aconcagua; 09.02.2018

Сигналы были protected в Qt4, в Qt5 они public. Int Qt5 вы можете сделать их private, добавив QPrivateSignal в качестве последнего аргумента. Подробнее об этом: http://woboq.com/blog/how-qt-signals-slots-work-part2-qt5.html

person Nikita Krupenko    schedule 29.09.2015
comment
Хороший прием: moc игнорирует последний элемент в сигнатуре сигнала, если имя QPrivateSignal - person Th. Thielemann; 09.11.2020

Слоты - это простые методы, которые могут быть общедоступными, защищенными или частными.

Как указал Андрей, signal - это всего лишь переопределение protected, то есть они могут быть отправлены только тем классом, в котором они определены.

Если вы хотите, чтобы класс излучал сигнал от другого, вы должны добавить ему общедоступный метод (или слот), подобный этому:

void emitTheSignal(...) {
  emit theSignal(...);
}
person gregseth    schedule 05.03.2010
comment
Я думаю, что это не ответ на вопрос ОП. Он имеет в виду сигналы, которые могут быть услышаны только классом, который их определил. - person Daniel; 22.07.2011
comment
они могут быть испущены только классом, в котором они определены ... Или классом друзей. ;) - person weberc2; 24.06.2013
comment
Я не уверен, что это правда. См. Здесь: stackoverflow.com/questions/19129133/ Сигналы docs cay могут исходить из других классов и всегда являются общедоступными, а не защищенными. - person johnbakers; 02.10.2013
comment
от qobjectdefs.h: #define signals protected, поэтому нет, сигналы не public. - person gregseth; 02.10.2013

Сигналы Qt являются общедоступными в том смысле, что любой объект может подключаться к любому сигналу.

person Kyle Lutz    schedule 26.01.2010
comment
они также являются общедоступными в том смысле, что их может генерировать любой другой класс, поскольку они являются общедоступными функциями. это могло измениться по сравнению с предыдущими версиями Qt. см. здесь stackoverflow.com/questions/19129133 / - person johnbakers; 02.10.2013
comment
В объектно-ориентированном программировании используется инкапсуляция, чтобы избежать доступа к внутренним методам и данным. Если сигналы предназначены только для внутренних целей, их тоже следует скрыть. - person Th. Thielemann; 09.11.2020

Все существующие ответы неверны.

Сигнал можно сделать закрытым, добавив к его определению тип QPrivateSignal в качестве последнего аргумента:

signals:
  
  void mySignal(QPrivateSignal);

QPrivateSignal - это частная структура, созданная в каждом QObject подклассе макросом Q_OBJECT, поэтому вы можете создавать только QPrivateSignal объектов в текущем классе.

Технически сигнал по-прежнему общедоступен, но он может быть испущен только классом, который его создал.

person Nicolas Holthaus    schedule 13.10.2020

Вы можете использовать для этого паттерн PIMPL. Ваши личные сигналы существуют только в частной реализации.

person Th. Thielemann    schedule 10.07.2019
comment
Разве PIMPL, производный от QObject, не утяжелит его и не ухудшит производительность? - person MasterAler; 08.11.2019
comment
Да, на это нужно время. Но рассмотрите следующие вопросы: сколько времени стоит вызов подпрограммы? Имеет ли значение производительность соответствующей программной части? - person Th. Thielemann; 10.11.2019
comment
Не уверен, почему это было отклонено. Я успешно использую этот подход, например, для оболочки конечного автомата, которая внутренне использует QStateMachine, но не раскрывает ее (по архитектурным причинам). Точно так же я не хочу раскрывать сигналы, используемые для того, чтобы конечный автомат выполнял свои переходы, поскольку в противном случае эти сигналы будут смешаны с сигналами общедоступного API, что снизит ремонтопригодность. Поскольку конечный автомат переключается только при взаимодействии с пользователем, влияние на производительность в моем случае совершенно не имеет значения. - person Tim Meyer; 09.11.2020