Нет.Случаи, в которых вы хотите искать что-то по идентификатору, - это примерно те же случаи, когда вам нужно искать что-то по идентификатору в C ++.Это применимо ко всем библиотекам виджетов, о которых я могу подумать - каждый раз, когда вы реагируете на сигнал с кодировкой some_standard_button_name
и соответствует метке, например ?wxID_OK
, вы ожидаете числовой идентификатор, представленный меткой, скрытой макросом.Большинство GUI-библиотек выполняют большую часть предварительной обработки, чтобы вымыть это, поэтому часто вы этого не замечаете (в случае библиотек sooper-dooper, таких как Qt, они все еще работают, только в фоновом режиме, и весь ваш код * 1003)* запустить прекомпилятор до того, как он станет "настоящим" C ++ ...).
Итак, как вы можете получить wx-штуку, которая была создана?Используя возвращенную ссылку.
Почти каждый вызов wx*:new()
возвращает ссылку на объект [note1].Это абстрактная ссылка (внутренне кортеж, но не рассчитывайте на это) с достаточным количеством информации для привязок Эрланга и процессов системы Wx, чтобы однозначно говорить о конкретных объектах Wx, которые были созданы.Передача этих ссылок является типичным способом доступа к объектам Wx позже:
GridSz = wxFlexGridSizer:new(2, 2, 4, 4),
ok = wxFlexGridSizer:setFlexibleDirection(GridSz, ?wxHORIZONTAL),
ok = wxFlexGridSizer:addGrowableCol(GridSz, 1),
Однако менее очевидный случай - когда вам нужно что-то вроде сетки полей ввода, которую вы можете циклически перемещать или перемещать позначение ключа:
Scripts = [katakana, hiragana, kanji, latin],
Ilks = [family, given, middle, maiden],
Rows = [{Tag, j(J, Tag)} || Tag <- Scripts],
Cols = [{Tag, j(J, Tag)} || Tag <- Ilks],
{GridSz, Fields} = zxw:text_input_grid(Dialog, Rows, Cols),
% Later on, extracting only present values as
Keys = [{S, I} || S <- Scripts, I <- Ilks],
Extract =
fun(Key, Acc) ->
case wxTextCtrl:getValue(proplists:get_value(Key, Fields)) of
"" -> Acc;
Val -> [{Key, Val} | Acc]
end
end,
NewParts = lists:foldl(Extract, [], Keys),
И так далее.( zxw: text_input_grid / 3 definition и docs )
Один раз, когда вы действительно хотите ссылаться на объект по его идентификатору, а не по ссылке на объект, этотак же, как в C ++: когда вы слушаете конкретное событие щелчка:
{AddressPicker, _, _, AddressSz} =
zxw:list_picker(Frame,
?widgetADDRESS, ?addADDRESS, ?delADDRESS,
AddressHeader, Addresses, j(J, address)),
, а затем в цикле обработки сообщений универсального wx_object:
handle_event(Wx = #wx{id = Id,
event = #wxCommand{type = command_button_clicked}},
State) ->
case Id of
?editNAME -> {noreply, edit_name(State)};
?editDOB -> {noreply, edit_dob(State)};
?editPORTRAIT -> {noreply, edit_portrait(State)};
?addCONTACT -> {noreply, add_contact_info(State)};
?delCONTACT -> {noreply, del_contact_info(State)};
?addADDRESS -> {noreply, add_address_info(State)};
?delADDRESS -> {noreply, del_address_info(State)};
_ ->
ok = unexpected(Wx),
{noreply, State}
end;
handle_event(Wx = #wx{id = Id,
event = #wxList{type = command_list_item_selected,
itemIndex = Index}},
State) ->
case Id of
?widgetCONTACT -> {noreply, update_selection(contact, Index, State)};
?widgetADDRESS -> {noreply, update_selection(address, Index, State)};
_ ->
ok = unexpected(Wx),
{noreply, State}
end;
Первое предложение касаетсяв частности, с помощью нажатий на нестандартные кнопки, а второй - с событиями выбора виджета управления списком, чтобы сделать некоторые произвольные вещи в интерфейсе.Хотя развертывание записи события #wx{}
не очень привлекательно для визуального отображения, использование соответствия в формировании предложения делает этот код GUI намного проще для понимания во время обслуживания, чем гигантский каскад проверок, исключений и последующих действий *Код типа 1031 *, switch
или case..break
и т. Д. Необходим для языков, в которых отсутствует соответствие.
В приведенном выше случае все конкретные идентификаторы помечены как макросы, точно одинаковокак это делается в Wx в C ++ и других наборах виджетов C ++. Большую часть времени ваши потребности удовлетворяются просто с помощью стандартных предопределенных типов кнопок Wx и соответствующей реакции на них;приведенный выше пример взят из кода, который вынужден нырнуть немного ниже, из-за некоторых особых требований к интерфейсу (и эквивалентный код C ++ сводится по существу к тому же, но значительно более многословному для выполнения той же задачи).
Некоторые платформы на языках чуть более высокого уровня имеют разные способы решения проблемы идентичности.Наборы виджетов для iOS и Android (и QtQuick, в этом отношении) скрывают эту деталь за чем-то вроде чуть более универсально полезной ссылки на объект, а не в зависимости от идентификаторов.То есть эти наборы виджетов по существу хранят все виджеты, созданные в хэше {ID => ObjReference}, выбирают идентификатор из каждого сигнала, извлекают ссылку на объект перед передачей управления в ваши обратные вызовы обработки и возвращают ссылку, сохраненную вхэш вместо простой передачи идентификатора напрямую.
Это замечательно, но не так, как работают старые наборы виджетов, привязанные к коду типа enums-as-label.Когда все сказанные и готовые компьютеры все еще имеют только один реальный тип: целые числа - мы придумываем всевозможные другие вещи поверх этого и наслаждаемся иллюзией типов и прочего веселья.
Мы могли бы сделать это -в Erlang также есть ссылки, но способ, которым код WxErlang обычно пишется, состоит в том, чтобы следовать традиции C ++, заключающейся в использовании идентификаторов объектов за метками макросов для событий, которые нельзя избежать уникальной идентификацией, и ссылок на объекты и стандартных меток для всего остального.
Библиотека zx_widgets, использованная выше, представляет собой набор предопределенных мета-виджетов, которые охватывают некоторые из наиболее распространенных случаев построения шаблонного поля и возвращают структуры данных, которые просты в обращении функционально.Стиль ООП Wx не совсем подходит для Erlang в некотором смысле (по этой причине самые длинные функции, которые вы когда-либо будете писать в Erlang, вероятно, будут кодом GUI), поэтому иногда для создания логики необходим дополнительный слойНосящий код вяжется с остальной частью Эрланга.Код GUI довольно универсален, но на любом языке и в любой среде.
[note1: Есть некоторые странные, неудобные случаи, когда некоторые тайны в стиле C ++ просачиваются через привязки в ваш Erlangкод, такой как процедура создания волшебной среды, используемая для использования 2D-графики DC холсты и еще много чего. ]