Frage

Ich habe mit Erlang wx Modul stochern und dieses Tutorial. Ich habe nicht verwendet wxwidgets vor, so vielleicht ist dies nur ist, wie es gemacht, aber dieser Code scheint wirklich schrecklich zu mir:

%% create widgets
    T1001 = wxTextCtrl:new(Panel, 1001,[]),
    ST2001 = wxStaticText:new(Panel, 2001,"Output Area", []),
    B101  = wxButton:new(Panel, 101, [{label, "&Countdown"}]),
    B102  = wxButton:new(Panel, ?wxID_EXIT, [{label, "E&xit"}]),
    wxFrame:show(Frame),

Haben die Leute haben wirklich assign Widget-IDs Widgets, wenn sie einrichten? Ist es normal, die Variable, dass die Punkte auf das Widget nach der Widget-ID zu nennen?

War es hilfreich?

Lösung

Ich weiß nicht, über Erlang aber in C ++ (und in den anderen Bindungen weiß ich) ist es oft vorzuziehen Verwendung wxID_ANY als Widget-ID, was bedeutet, dass Sie sich nicht um seinen spezifischen Wert egal, und dann Connect() verwenden Ereignisse aus dem Widget zu behandeln. Explizite ids kann zweckmäßig sein, wenn Sie das Widget durch seine ID später finden müssen (obwohl Sie auch die Namen für diese verwenden Widget können) oder wenn Sie eine fortlaufende Bereich für ids benötigen (zB wäre es sinnvoll zu verwenden ids 100, 101, zu machen. .., 109 für die Tasten eines Rechners, wie Sie könnten dann ableiten, leicht jeden Taste Wert von seinem id), aber es gibt keine Notwendigkeit, sie immer verwenden.

Wie für die Namensgebung gibt es, natürlich, keine Notwendigkeit, diese seltsame Konvention zu verwenden (und einen kurzen Blick auf den Tutorial zeigen, dass es eine persönliche Vorliebe des Autors ist - was unnötig zu sagen, weiß ich nicht Aktie).

Andere Tipps

Wie VZ oben erwähnt, können Sie wxID_ANY verwenden, wenn Sie nicht brauchen, wird später ein Widget durch seine ID Lookup.

Ich glaube jedoch, dass es nicht nur nicht normal ist, die Variablen nach dem IDs zu nennen, sondern es ist eine sehr schlechte Idee, dies zu tun. Benennen Sie Ihre Variablen entsprechend ihrer Bedeutung und nicht etwas obskuren ID mit .

Außerdem würde Sie definieren besser die ids Sie brauchen, und geben ihnen die richtige (semantische) Namen, so dass sie nur an einer Stelle definiert sind, und Sie können ohne Beeinträchtigung der Ihr Programm überhaupt später leicht die IDs ändern, wie folgt aus:

-define(ID_TEXT_CTRL, 1001).
-define(ID_OUTPUT_AREA, 2001).
-define(ID_COUNTDOWN_BUTTON, 101).
-define(ID_EXIT_BUTTON, ?wxID_EXIT).

TextCtrl = wxTextCtrl:new(Panel, ?ID_TEXT_CTRL,[]),
OutputArea = wxStaticText:new(Panel, ?ID_OUTPUT_AREA,"Output Area", []),
CountdownButton  = wxButton:new(Panel, ?ID_COUNTDOWN_BUTTON, [{label, "&Countdown"}]),
ExitButton  = wxButton:new(Panel, ?ID_EXIT_BUTTON, [{label, "E&xit"}])

Sie können die Definitionen setzen entweder in Ihrer .erl Datei, wenn es eine ist nur, oder in einer .hrl-Datei, die Sie in Ihre GUI-bezogene .erl Dateien enthalten müssen werden.

Nein. Die Fälle, in denen man sich nur wünschen, etwas zu sehen von ID sind in etwa die gleichen Fälle, in denen Sie zu sehen etwas nach oben von ID in C ++ wünschen würde. Dies gilt für jede Widget-Bibliothek ich mir vorstellen kann - jedes Mal, wenn Sie auf ein Signal codiert some_standard_button_name reagieren und stimmt mit einem Label wie ?wxID_OK Sie für eine numerische ID warten, die von einem Makro versteckt durch ein Etikett dargestellt wird. Die meisten GUI-Bibliotheken haben eine Menge Vorverarbeitung diese heraus zu waschen, sie so oft bemerken es nicht (im Fall von sooper-dooper Bibliotheken wie Qt seine geht nach wie vor, nur im Hintergrund, und alle Ihre Code über einen Precompiler ausführen, bevor es wird "real" C ++ ...).

Wie bekommen Sie einen Halt eines wx Dingen das ist erstellt worden? Mit seiner zurück Referenz.

Fast jeder wx*:new() Aufruf gibt einen Objektverweis [note1]. Dies ist eine abstrakte Referenz (intern ein Tupel, aber rechnen Sie nicht, dass) genügend Informationen für die Erlang-Bindungen und die Wx Systemprozesse eindeutig zu bestimmten Wx Objekten zu sprechen, die erstellt wurden. diese Referenzen um Vorbei ist die typische Art und Weise Wx für den Zugriff auf Objekte später:

GridSz = wxFlexGridSizer:new(2, 2, 4, 4),
ok = wxFlexGridSizer:setFlexibleDirection(GridSz, ?wxHORIZONTAL),
ok = wxFlexGridSizer:addGrowableCol(GridSz, 1),

Ein weniger offensichtlicher Fall, obwohl, ist, wenn Sie so etwas wie ein Raster von Eingabefeldern wollen, dass Sie durchlaufen oder Pull durch Schlüsselwert:

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),

Und so weiter. ( zxw: text_input_grid / 3 Definition und docs )

Das ein Mal, wenn Sie wirklich wollen ein Objekt durch seine ID verweisen und nicht seine Objektreferenz ist das gleiche wie in C ++: Wenn Sie für ein bestimmte Klick-Ereignis hören:

{AddressPicker, _, _, AddressSz} =
    zxw:list_picker(Frame,
                    ?widgetADDRESS, ?addADDRESS, ?delADDRESS,
                    AddressHeader, Addresses, j(J, address)),

Und dann später in der Nachrichtenbehandlung Schleife des generischen 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;

Die erste Klausel befasst sich speziell mit Klicks auf Nicht-Standard-Tasten und die zweite mit list-Steuer Widget Auswahl Ereignisse einige beliebige Dinge in der Schnittstelle zu tun. die #wx{} Ereignisaufzeichnung ist nicht optisch sehr ansprechend, mit Matching in Klausel Bildung Während Abwickeln macht diesen GUI-Code viel leichter bei der Wartung als die gigantische Kaskade von Schecks, Ausnahme abfängt und Folge auf if elif elif elif elif... zu verstehen, switch oder case..break usw. Typencode notwendig in Sprachen, die passende fehlen.

Im obigen Fall alle entsprechenden IDs als Makros markiert sind, genau die gleiche Art und Weise dies in Wx in C ++ durchgeführt wird und andere C ++ Widget-Kits. Die der Zeit werden Ihre Bedürfnisse bedient, indem einfach die Standard vordefinierte mit Wx Schaltfläche Typen und entsprechend darauf reagieren; Das obige Beispiel von Code ist, weil ein Bit zu tauchen einiger spezifischer Schnittstellenanforderungen unterhalb gezwungen wird (und die äquivalente C ++ Code aufwickelt im wesentlichen die gleiche, aber dramatisch ausführlicher die gleiche Aufgabe zu erfüllen).

Einige Plattformen in etwas höheren Ebene Sprachen haben verschiedene Möglichkeiten, mit der Identität Problem beschäftigen. iOS und Android-Widget-Kits (und QtQuick, was das betrifft) verstecken dieses Detail hinter so etwas wie ein etwas universell einsetzbar Objektverweis nicht abhängig von IDs. Das ist jene Widget-Kits zu sagen, im Wesentlichen alle Widgets in einem Hash erstellt speichern {ID => ObjReference}, wählen Sie die ID aus jedem Signal, den Objektverweis abrufen, bevor die Steuerung zu Ihren Umgang mit Rückrufe vorbei und kehren den Verweis in die gespeicherte Hash statt nur die ID durch direkt übergeben.

Das ist glatt, aber es ist nicht die Art und Weise ältere Widget-Kits gebunden C-Stil Aufzählungen-as-Etiketten-Code zu arbeiten. Wenn seine alles gesagt und getan Computer nach wie vor nur eine wirkliche Art haben: ganze Zahlen - wir alle möglichen anderen Sachen auf dieses erfinden und die Illusion von Arten genießen undanderer Spaß.

Wir könnten auch diese ID-to-Referenz Sache in Erlang, aber die Art und Weise WxErlang Code typischerweise geschrieben wird, ist der C ++ Tradition zu folgen, der für Ereignisse hinter Makro-Etikett Objekt-IDs verwenden Sie eindeutig nicht vermeiden können, zu identifizieren und Objekt Referenzen und Standardetiketten für alles andere.

Das oben eingesetzte zx_widgets Bibliothek ist ein Satz von vordefinierten meta-Widgets, die einige der häufigsten Fälle von vorformulierten Bereich Bau und Rückgabedatenstrukturen umfassen, die einfach sind funktionell zu handhaben. Der OOP-Stil Wx ist nicht eine sehr natürliche Ergänzung für Erlang in gewisser Weise (die looooooongest Funktionen, die Sie jemals aus diesem Grunde in Erlang sind wahrscheinlich sein GUI-Code schreiben werden), so dass eine zusätzliche Schicht manchmal notwendig ist, um die Logik zu machen -substituierte Code Stichelei mit dem Rest von Erlang. GUI-Code ist ziemlich universell ärgerlich, aber in jeder Sprache und in jeder Umgebung.

[note1. Es gibt einige seltsamen, unangenehme Fälle, in denen ein paar C ++ - Stil Geheimnisse durch die Bindungen in der Erlang-Code Leck, wie die magische Umgebung Erzeugungsprozedur bei der Verwendung von 2D-Grafiken DC Leinwände und so weiter ]

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top