Какова правильная идиома Qt для демонстрации сигналов / слотов содержащихся виджетов? - PullRequest
19 голосов
/ 01 апреля 2010

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

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

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

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

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

Ответы [ 3 ]

19 голосов
/ 01 апреля 2010

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

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

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

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

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

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

0 голосов
/ 01 апреля 2010

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

0 голосов
/ 01 апреля 2010

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

...