Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.02.26;
Скачать: CL | DM;

Вниз

Большие сложные GUI   Найти похожие ветки 

 
Kerk ©   (2011-11-09 06:58) [0]

Хорошую штуку придумали в Delphi -- TAction. Это делает управление интерфейсом намного проще. Но что вы делаете, когда возможных состояний и зависимостей становится слишком много? Как боретесь с растущей сложностью GUI? Поделитесь лучшими практиками.


 
Petr V. Abramov ©   (2011-11-09 09:27) [1]


> Но что вы делаете, когда возможных состояний и зависимостей
> становится слишком много?

упрощаем консерваторию, если ты начинаешь путаться, значит, пользователь точно хрен чего поймет в этой форме.


 
Омлет ©   (2011-11-09 09:30) [2]

Пока что фреймы спасают.


 
Сергей М. ©   (2011-11-09 09:40) [3]

Мне, к примеру, ни разу не удалось запутаться в экшнах, которые я наплодил)..  В одном из проектов, помнится, их было под сотню-полторы.. Может это и немного на субъективный взгляд, но тем не менее)

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


 
Kerk ©   (2011-11-09 09:43) [4]


> Petr V. Abramov ©   (09.11.11 09:27) [1]

Пользователь никогда не увидит то, что вижу я. Для него интерфейс контекстно-зависим, в каждый момент он видит только его часть.


 
Kerk ©   (2011-11-09 09:51) [5]


> Сергей М. ©   (09.11.11 09:40) [3]

Проблема не только в количестве самих TAction.

Например, некоторый TSomeAction видим, если в дереве выбран объект типа A, но невидим, если выбран объект типа B. При этом его свойство Enabled зависит от некоторых свойств этого объекта A. Плюс к этому поверх условие, что TSomeAction.Enabled зависит от состояния приложения (Connected/Disconnected).

Ну и таких вот условий, скажем, сотня. Каждому писать OnUpdate упаришься. Вижу выход в разбиении всех TAction на какие-то группы, но пока не придумал как.


 
Сергей М. ©   (2011-11-09 10:10) [6]


> Kerk ©   (09.11.11 09:51) [5]


> Вижу выход в разбиении всех TAction на какие-то группы


Ну группировать разносортные экшны так или иначе надо, иначе в глазах от них запестрит)
Может даже придется и не один экшн-лист создавать и продумывать взаимодействие между ними на событийном уровне  ..


 
Ega23 ©   (2011-11-09 10:28) [7]


> Ну и таких вот условий, скажем, сотня.


Я с трудом могу представить такой конечный автомат. Которому нельзя декомпозицию сделать. А значит - см. [1].
ИМХО.


 
Kerk ©   (2011-11-09 13:24) [8]

Как-то у нас бестолково получается, хотя вроде бы все всё верно говорят :)

Понятно, что лучше быть здоровым и богатым, чем бедным и больным. Но я хотел послушать о реальных случаях. Например, "у меня было XXX, я сделал YYY и ZZZ, получилось AAA".


 
Ega23 ©   (2011-11-09 13:34) [9]


>  Но я хотел послушать о реальных случаях. Например, "у меня
> было XXX, я сделал YYY и ZZZ, получилось AAA".


1. Разрисовать конечный автомат.
2. Аккуратно закодировать.
А какие ещё могут быть варианты?


 
Jeer ©   (2011-11-09 14:17) [10]


> 1. Разрисовать конечный автомат.


+1

P.S.
Понятно, что программирование на сегодня перетекло в русло событийных методов, но забывать функциональные - все же не стоит.
Значительная "событийность" разрушает связанность тела программы и прогеру все сложнее по листингу "перед глазами" видень "картину маслом".


 
Кто б сомневался ©   (2011-11-09 14:39) [11]


> Как боретесь с растущей сложностью GUI? Поделитесь лучшими
> практиками.


Делать Gui в виде Wizard"a . Лучший вариант.


 
Игорь Шевченко ©   (2011-11-09 21:20) [12]

Kerk ©   (09.11.11 09:51) [5]


> Например, некоторый TSomeAction видим, если в дереве выбран
> объект типа A, но невидим, если выбран объект типа B.


Можно разносить Actions по разным ActionLists и процедуры обновления переносить в эти Lists.


 
Eraser ©   (2011-11-09 21:47) [13]

> [5] Kerk ©   (09.11.11 09:51)

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


 
Kerk ©   (2011-11-09 21:54) [14]


> Игорь Шевченко ©   (09.11.11 21:20) [12]

Я пока к такому и склоняюсь. К разбиению на какие-то логические группы с похожими правилами апдейта.

> Eraser ©   (09.11.11 21:47) [13]

Вот оно примерно так сейчас и есть, но это очень тяжело сопровождать.


 
Eraser ©   (2011-11-09 22:12) [15]

> [14] Kerk ©   (09.11.11 21:54)


> Вот оно примерно так сейчас и есть, но это очень тяжело
> сопровождать.

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


 
Kerk ©   (2011-11-09 22:18) [16]

Это не дело вкуса. Код, разбитый по смыслу, куда более проще воспринимается, чем полотно из 500 строк :)


 
Jeer ©   (2011-11-09 22:56) [17]

Код разбитый на сообщения, воспринимается сложнее, чем код связанный "течением".
Вопрос в разумном компромиссе того и этого.


 
Petr V. Abramov ©   (2011-11-09 23:06) [18]


> Kerk ©   (09.11.11 09:51) [5]
>
>
> > Сергей М. ©   (09.11.11 09:40) [3]
>
> Проблема не только в количестве самих TAction.
>
> Например, некоторый TSomeAction видим, если в дереве выбран
> объект типа A, но невидим, если выбран объект типа B. При
> этом его свойство Enabled зависит от некоторых свойств этого
> объекта A. Плюс к этому поверх условие, что TSomeAction.
> Enabled зависит от состояния приложения (Connected/Disconnected).
>
>
> Ну и таких вот условий, скажем, сотня. Каждому писать OnUpdate
> упаришься. Вижу выход в разбиении всех TAction на какие-
> то группы, но пока не придумал как.

ну это почти классика.
группируешь акшны по типу объекта. например по разным акшнлистам
находишь/придумываешь событие ObjTypeChange (это может быть onchange дерева в простейшем случае)
на этом событии выставляешь hide текущему видимому листу, visible новому, enable акшнам в зависимости от св-в объекта и расположения звезд
profit


 
Макс Черных   (2011-11-10 01:05) [19]

На самом деле кажущаяся неудобность TAction в смысле - куча событий и все такое возникает от забытия/непонимания того, что незачем везде и всюду использовать именно класс TAction. Кто мешает наделать свои классы - наследники TAction. И не надо кучи ActionList или тонны кода в одном месте.

Еще один пользительный трюк - это использование интерфейсов, применительно к наследникам TCustomAction. Т.е. когда свой класс  TAction реагирует на то поддерживает ли Тarget некий управляющий интерфейс, и если да, то взаимодействует с ним.
Это позволяет четко разнести логику интерфейса и реакцию на события не смешивая все в одну кашу. Кроме того, если вдруг нужно сделать поддержку этих Action в неком новом месте, то достаточно там реализовать управляющий интерфейс (в том числе и через делегирование). И все работатет, при этом сама Action и знать не знает, что ей новый контрол или чего подсунули.


 
И. Павел ©   (2011-11-10 10:13) [20]

> Каждому писать OnUpdate упаришься.

Если код для определения Enabled и Visible выполняется не долго (а как правило так оно и есть), то можно его из JnUpdate переместить в onIdle, и там вычислять доступность всех элементов формы друг за другом - все будет в одном месте и взаимосогласовано.


 
Kerk ©   (2011-11-10 10:17) [21]


> Макс Черных   (10.11.11 01:05) [19]

О, вот это очень интересно. Спасибо :)
Но TActionList умеет ли визуально редактировать другие классы - наследники TCustomAction ?


 
Ega23 ©   (2011-11-10 10:20) [22]


>  умеет ли визуально редактировать другие классы - наследники
> TCustomAction ?


Вроде да.


 
Бездомный   (2011-11-10 11:51) [23]

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

Например:

Где вы обычно обновляете свойство Enabled?

В OnUpdate или событиях других контролов?


 
MsGuns ©   (2011-11-10 11:54) [24]

TActionList+TImageList использую чуть ли не с первого года юзания делфи, по-моему Johnman мне когда-то подсказал этот "путь"ю
С тех пор "на автомате" использую его даже в пустячных, разовых проектиках.

Стараюсь использовать максимально централизованное управление, поэтому ессно оба компонента - в MainForm. Хотя бы потому, что в любой из "дочерних" в случае крайней необходимости можно было бы "дернуть" нужный экшн.
1) Все акции - по группам, как правило в строгом соответствии с деревом главного меню и инструментальными линейками (TControlBar+TToolBar`s по числу пунктов гл.меню)
2) Процедура SwitchMainAction (или вроде этого), переключающая акшины (enable/diable, imageindex, hint etc) контекстно. Из любого места проекта после соотв.действий (например открытия датасета) - вызов этого метода.
3) В подчиненных таблицах при необходимости попапменю - ссылка на ту же "сладкую" парочку
4) Библиотечные процедуры, написанные именно с целью убрать из проектов "стандартные" участки кода, в т.ч. и процедуры, "гасящие" экшины указанной группы.
5) Максимально полный отказ от реализующего функционал кода в самих обработчиках экшн - только в целевых процедурах/функциях
6) Максимальная реализация экшнов в гл.форме, с использованием RTTI если необходимо

Кстати, такая схема прекрасно подходит и к MDI, и к SDI


 
MsGuns ©   (2011-11-10 12:02) [25]

Есть, кстати, один недостаток, с которым бороться так и не научился :(
При любой модификации списка "наклеек" в TImageList идет соотв. переиндексация и все кнопки "путаются" - надо потом спец.проходом возвращать каждой ее картинку. Особенно неприятно при правках большого по объему списка.


 
Ega23 ©   (2011-11-10 12:10) [26]


>  поэтому ессно оба компонента - в MainForm.


Это не "ессно". Это твоё субъективное мнение.


 
clickmaker ©   (2011-11-10 12:24) [27]

ImageList можно вынести в DataModule. Удобно, если одни и те же кнопки в разных формах


 
MsGuns ©   (2011-11-10 12:27) [28]

DataModule, MainForm - не существенно. Главное, чтобы модуль был виден из дочерних.


 
Ega23 ©   (2011-11-10 12:32) [29]


>  Главное, чтобы модуль был виден из дочерних.


У тебя главная форма видна из "дочерних"???


 
MsGuns ©   (2011-11-10 13:02) [30]

Не всегда, когда не видна, я использую сообщения :)
Но в общем-то обычно да. А что, из "джидаев" за это выгоняют ?


 
Макс Черных   (2011-11-10 19:26) [31]


> Но TActionList умеет ли визуально редактировать другие классы
> - наследники TCustomAction ?


TActionList умеет только добавлять/удалять любые потомки TCustomAction, в том числе и TAction. А свойствами TCustomAction рулит object inspector. Т.е. чего в published наваяли, то и увидели. Все стандартно.


 
Kerk ©   (2011-11-10 19:33) [32]


> Макс Черных   (10.11.11 19:26) [31]

Накопал статью http://www.kudzuworld.com/articles/Actions/index.EN.aspx
То, что нужно. Спасибо. Не знал про RegisterActions().



Страницы: 1 вся ветка

Текущий архив: 2012.02.26;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.011 c
15-1320861739
Вспученный
2011-11-09 22:02
2012.02.26
Как посмотреть видео в контакте с ошибкой доступа?


15-1320485519
RDen
2011-11-05 12:31
2012.02.26
Свернуть все окна в Win XP


2-1321475790
DnoProgrammer
2011-11-17 00:36
2012.02.26
свой Opendialog


2-1321607338
TeaNick
2011-11-18 13:08
2012.02.26
Проверка принадлежности перечислимому типу.


2-1321864635
megagenom
2011-11-21 12:37
2012.02.26
Мониторинг свободного пространства на удаленном сервере.