3

私はErlangのwxモジュールとこのチュートリアルをいじくり回してきました。私はこれまでwxwidgetsを使用したことがないので、おそらくこれがその方法ですが、このコードは私には本当にひどいようです。

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

ウィジェットを作成するときに、ウィジェットIDをウィジェットに割り当てる必要が本当にありますか?ウィジェットのIDにちなんで、ウィジェットを指す変数に名前を付けるのは正常ですか?

4

3 に答える 3

8

Erlangについてはわかりませんが、C ++(および私が知っている他のバインディング)ではwxID_ANY、ウィジェットIDとして使用することをお勧めします。つまり、特定の値を気にせず、Connect()からのイベントを処理するために使用します。ウィジェット。明示的なIDは、後でそのIDでウィジェットを検索する必要がある場合(ただし、ウィジェット名を使用することもできます)、またはIDに連続した範囲が必要な場合(たとえば、ID 100、101、を使用するのが理にかなっている場合)に便利です。 ..、電卓のボタンの場合は109です。これは、IDから各ボタンの値を簡単に推測できるためです)が、常にそれらを使用する必要はありません。

ネーミングに関しては、もちろん、この奇妙な慣習を使用する必要はありません(そして、チュートリアルをざっと見てみると、それは作者の個人的な好みであることがわかります-言うまでもなく、私は共有しません)。

于 2010-11-19T17:15:02.710 に答える
5

上記のVZと同様に、後でウィジェットをIDで検索する必要がない場合は、wxID_ANYを使用できます。

ただし、IDにちなんで変数に名前を付けるのは普通ではないだけでなく、そうすることは非常に悪い考えだと思います。あいまいなIDを使用せずに、意味に従って変数に名前を付けます

また、必要なIDを定義し、適切な(意味のある)名前を付けて、1つの場所でのみ定義され、後でプログラムにまったく影響を与えることなくIDを簡単に変更できるようにすることをお勧めします。

-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"}])

定義は、.erlファイルが1つしかない場合はファイルに入れるか.hrl、GUI関連のすべてのファイルに含める必要があるファイルに入れることが.erlできます。

于 2010-11-21T23:03:32.650 に答える
1

いいえ。IDで何かを検索したい場合は、C++でIDで何かを検索したい場合とほぼ同じです。これは、私が考えることができるすべてのウィジェットライブラリに当てはまります。コード化された信号に反応し、マクロによって隠されたラベルで表される数値IDを待っているsome_standard_button_nameようにラベルと一致するたびに。?wxID_OKほとんどのGUIライブラリは、これを洗い流すために多くの前処理を行うため、気付かないことがよくあります(Qtのようなsooper-dooperライブラリの場合、バックグラウンドで実行され、すべてのコードが実行されます。 「実際の」C++になる前のプリコンパイラ...)。

では、作成されたwxthingyをどのように入手しますか?返された参照を使用する。

ほとんどすべてwx*:new()の呼び出しは、オブジェクト参照[note1]を返します。これは抽象的なリファレンス(内部的にはタプルですが、それを当てにしないでください)であり、Erlangバインディングと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定義、およびドキュメント

オブジェクト参照ではなくIDでオブジェクトを実際に参照したい場合は、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;

最初の句は特に非標準のボタンのクリックを扱い、2番目の句はインターフェイスで任意のことを行うためのリストコントロールウィジェット選択イベントを扱います。イベントレコードのアンラップは#wx{}視覚的にあまり魅力的ではありませんが、句の形成に一致を使用すると、このGUIコードは、言語で必要なチェック、例外キャッチ、後続などのタイプコードの巨大なカスケードよりも、メンテナンス中にはるかに理解しやすくなります。マッチングが不足しています。if elif elif elif elif...switchcase..break

上記の場合、すべての特定のIDはマクロとしてラベル付けされます。これは、C++およびその他のC++ウィジェットキットのWxで行われるのとまったく同じ方法です。ほとんどの場合、標準の事前定義されたWxボタンタイプを使用し、それに応じて対応するだけで、ニーズに対応できます。上記の例は、特定のインターフェイス要件のために、それより少し下に潜ることを余儀なくされたコードからのものです(そして、同等のC ++コードは本質的に同じになりますが、同じタスクを実行するために劇的により冗長になります)。

わずかに高水準言語の一部のプラットフォームでは、IDの問題を処理する方法が異なります。iOSおよびAndroidウィジェットキット(さらに言えば、QtQuick)は、IDに依存するのではなく、もう少し普遍的に役立つオブジェクト参照のようなものの背後にこの詳細を隠します。つまり、これらのウィジェットキットは、基本的に{ID => ObjReference}のハッシュで作成されたすべてのウィジェットを格納し、すべてのシグナルからIDを選択し、処理コールバックに制御を渡す前にオブジェクト参照を取得し、格納されている参照を返します。 IDを直接渡すのではなく、ハッシュします。

これは洗練されていますが、Cスタイルのenums-as-labelsコードにバインドされた古いウィジェットキットが機能する方法ではありません。すべてが言われ、実行されたコンピューターがまだ1つの実際の型、つまり整数しか持っていないとき、私たちはこれに加えて他のあらゆる種類のものを発明し、型の錯覚やその他の楽しみを楽しんでいます。

このIDから参照への変換はErlangでも実行できますが、WxErlangコードの通常の記述方法は、一意の識別を避けられないイベントのマクロラベルの背後にあるオブジェクトID、およびオブジェクト参照と標準を使用するというC++の伝統に従うことです。他のすべてのラベル。

上記で使用されているzx_widgetsライブラリは、ボイラープレートフィールド構築の最も一般的なケースのいくつかをカバーし、機能的に処理しやすいデータ構造を返す、事前定義されたメタウィジェットのセットです。WxのOOPスタイルは、いくつかの点でErlangにあまり自然に適合していません(このため、Erlangで作成する最もlooooooongest関数はGUIコードである可能性があります)。そのため、ロジックを作成するために追加のレイヤーが必要になる場合があります。 -Erlangの残りの部分と一緒にコードjibeを持っています。ただし、GUIコードは、どの言語でも、どの環境でも、かなり普遍的に迷惑です。

[注1:2DグラフィックスDCキャンバスの使用に関連する魔法の環境作成手順など、いくつかのC++スタイルの謎がバインディングを介してErlangコードに漏れるという奇妙で不快なケースがいくつかあります。]

于 2015-12-31T06:53:25.423 に答える