Подтвердить что ты не робот

Какая правильная Qt-идиома для разоблачения сигналов/слотов содержащихся виджетов?

Предположим, что у меня есть MyWidget, который содержит a MySubWidget, например. пользовательский виджет, который содержит текстовое поле или что-то еще. Я хочу, чтобы другие классы могли подключаться к сигналам и слотам, которые были открыты с помощью экземпляра MySubWidget. Это обычный способ сделать это:

  • Выведите указатель на экземпляр MySubWidget с помощью метода subWidget() в MyWidget
  • Дублируйте сигналы и слоты MySubWidget в классе MyWidget и напишите код пересылки
  • Что-то еще?

Выбор 1 выглядит как наименьший код, но он также представляет собой разрывы инкапсуляции, так как теперь другим классам известно, что содержащиеся в нем виджеты MyWidget являются и могут зависеть от их функциональности.

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

Что обычно делается в этой ситуации?

4b9b3361

Ответ 1

Если вы посмотрите на собственный код Qt, они предпочитают вариант 2.

Например, посмотрите QTabWidget и QTabBar. Они имеют ряд сигналов и слотов, но QTabWidget скрывает тот факт, что использует QTabBar (ну, sorta... QTabWidget::tabBar(), очевидно, нарушает это, даже если он защищен).

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

Не забывайте, что вы можете подключать сигналы к таким сигналам:

connect(mySubWidget, SIGNAL(internalSignal(int)), this, SIGNAL(externalSignal(int)));

Что сделает MyWidget emit externalSignal(int), когда MySubWidget испускает internalSignal(int). Это помогает, по крайней мере, с сигнальной стороны вещей. К сожалению, я не знаю, какой простой способ сделать то же самое для слотов.

Ответ 2

Я бы не стал беспокоиться об инкапсуляции сигналов и слотов, по-видимому, только одна вещь делает соединение, так что вред в нем знает о некоторых подклассах? Если вы работаете над более крупной командой, предотвращая злоупотребление методом subWidget(), вы можете сделать это с помощью ключевого слова friend или любого другого...

Ответ 3

Вы можете открыть базовый класс MySubWidget, который будет содержать меньше функциональности.