2010-08-03 6 views
1

Допустим, мы имеем follogin UI:сигналы и слоты в многослойных виджетов UI

+--------------------------+ 
|W1  +--------------+ | 
|   |W2   | | 
|   | +----------+ | | 
|   | |W3  | | | 
|   | +----------+ | | 
|   |    | | 
|   +--------------+ | 
+--------------------------+ 

W3 заинтересован в определенном сигнале emited в W1 (или уровня ниже, т.е. qApp).

Идея заключается в разработке W3 независимо. Но кто-то должен выполнить соединение с сигналом/слотом.

Что было бы хорошей практикой/рекомендуемым способом подключения сигнала, излучаемого в W1, в слот в W3, если мы хотим, чтобы W3 не знал о каком-либо другом виджетах, и мы не хотим, чтобы W1 знал о W3?

Решение 1: Подключите сигнал в W1 с сигналом в W2 (сигнал к сигнальной технике) и, следовательно, подключите сигнал в W2 к разъему в W3.

Решение 2: Генерировать сигнал qApp и подключать его в W2 со слотом в W3.

Решение 3: Создайте сигнал qApp и подключите к нему W3, используя собственный слот.

Благодаря

ответ

3

Обычно охватывающий виджет инкапсулирует виджеты внутри него и обеспечивает интерфейс более высокого уровня. Например, если W3 содержит несколько виджетов, которые должны быть включены/отключены в зависимости от некоторого состояния, W3 будет управлять этим состоянием, предоставлять API для него и соответственно включать/отключать виджеты. Поэтому обычно нет необходимости напрямую переходить от W1 к W3.

Если виджеты не знают друг о друге (например, b/c W1 - общий виджет контейнера, который может вставлять что-либо), то тот, кто собирает пользовательский интерфейс, зная все задействованные виджеты, должен установить соединение.

Я не знаю, что вы подразумеваете под «сигналом qApp», но это звучит слишком сильно, как на центральном объекте, связанном со всем, что, конечно же, не является хорошим дизайном.

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

+0

Спасибо за ваш ответ. Я думаю, что имеет смысл просто инкапсулировать то, что нужно W3 в W2. W2 просто нужно выставить слот, и тот, кто подключает их, будет отвечать за этот слот, который будет вызван. После этого W2 будет использовать эту информацию для W3. *** qApp - это макрос, который поставляется с Qt для доступа к объекту QApplication и доступен из любого места в коде, который имеет в нем свои корни.Сигналы, испущенные в экземпляре QApplication, можно связать, выполнив: connect (qApp, SIGNAL (someCustomSignal()), это, SLOT (someSlot())); – Daniel

+0

Да, тогда я правильно понял вашу идею qApp. (и мой критический аргумент против него применяется;)). Лично я избегаю использования QApplication в виджетах, насколько это возможно. Предполагая, что некоторый подкласс QApplication с пользовательскими сигналами/слотами связывает его еще больше. Обычно я вообще не подклассифицирую QApplication. Я предпочитаю, чтобы некоторые виджеты знали друг о друге, а не связывали их неявно и хорошо скрывали через всемогущий объект QApplication. –

1

Подход, который мы используем здесь в том, что «оболочка» делает соединение.

Оболочка - это объект, который знает обо всех виджетах. В этом случае W1, W2 и W3. Обычно это код, который собирает пользовательский интерфейс.

Если оболочка не знает о W3 (поскольку, например, W3 является деталью реализации), тогда «владелец» W3 должен установить соединение и так далее.

+0

Спасибо за ответ. Проблема, которую я нахожу с вашим подходом, состоит в том, что если W3 содержит другой виджет W4, который, в свою очередь, содержит W5 и т. Д., И последний виджет в цепочке должен знать о сигнале, испускаемом из W1, это означало бы сделать соединение на каждом уровне. Является ли это приемлемым в обычной практике? – Daniel

+0

Являются ли W4, W5 и т. Д. Частью открытого интерфейса W3? Если они есть, и соединения не требуются для работы всего композита, сделайте это за пределами W3. Иначе, инкапсуляция будет нарушена. – andref