Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2012.02.26;
Скачать: [xml.tar.bz2];

Вниз

Большие сложные 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.004 c
2-1321098441
a101081
2011-11-12 15:47
2012.02.26
StrToFloat()


15-1320820793
stas
2011-11-09 10:39
2012.02.26
TwebBrowser и Socks, реально?


15-1320492248
alexdn
2011-11-05 14:24
2012.02.26
Компонент для XE2


2-1321739730
3asys
2011-11-20 01:55
2012.02.26
PowerPoint в OleContainer


2-1321443234
Scott Storch
2011-11-16 15:33
2012.02.26
подождать завершения работы процедуры





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский