TCLで辞書を使用する

こんにちは、Habr! %ユーザー名、おそらくtclのような言語とそのグラフィカルツールキットtkについて聞いたことがあるでしょう。 言語は特に柔軟です(私の謙虚な意見では)。 「クラウド」開発について書く時間はあまりありませんが、素晴らしいtcl言語の機能の1つである辞書についてのミニ記事/ミニレッスンを書くことにしました(そして、「Practical Programming in Tcl / TK」からは覚えていないかもしれません。古いバージョンを読んでください)。 このデータ型の最も完全な説明、%username、 リンクで見つけることができます。



ちょっとした理論-tclのディクショナリは、キー値型の複雑な順序付けられた値を格納できるデータ型で、ツリー自体を分岐する機能があります。 つまり、1つのキー(たとえば、レコードID)に対して、1つの値ではなく、値を持つ複数のキーが存在する可能性があります。 tcl構文では次のようになります。

dict set nonUserSettings 0 title "myProgram" dict set nonUserSettings 0 minWidth 800 dict set nonUserSettings 0 minHeight 600 dict set nonUserSettings 0 resizableX 1 dict set nonUserSettings 0 resizableY 1
      
      





このコードは何をしますか? すべてが単純です-title、minWidth、minHeight、resizableX、resizableYの属性を持つprogramSettings辞書を作成します。 さらに、ディクショナリ内の要素のIDにより、プログラムの他のルートウィンドウの設定をこすることができます(マルチウィンドウを実行する場合は、これが必要になる場合があります

インターフェース)。



辞書から値にアクセスするには、次のコマンドを使用します。

 dict get <-> <>
      
      





辞書を使用してTkウィンドウを描画しましょう。 通常のコードは次のようになります。

 wm title . "myProgram" wm resizable . 1 1 wm minsize . 800 600
      
      





コードは次のようになります。

 wm title . [dict get $nonUserSettings 0 "title"] wm resizable . [dict get $nonUserSettings 0 "resizableX"] [dict get $nonUserSettings 0 "resizableY"] wm minsize . [dict get $nonUserSettings 0 "minWidth"] [dict get $nonUserSettings 0 "minHeight"]
      
      





それは私たちに何を与えますか? 本質的に、辞書(実際、tcl内のすべてのデータ)は変更可能です。 したがって、再定義できます。 したがって、ディクショナリから取得した値をオーバーライドすると、ウィンドウが変更されます。 この場合、プログラムを再起動する必要はありません。 つまり、GUI設定は動的に選択されます。 ただし、これらはすべてリストを使用して簡単に実装できます。 それなら、なぜ辞書を使う必要があるのでしょうか。 まず、辞書を使用するとプログラムが読みやすくなり、そのデータがより体系化されます(実際、コード内に何らかのデータベーステーブルを保持します)。 そしてもう一方で...私は今あなたを紹介します。



通常のトップメニューを作成する必要があるとします。 ウィジェットのように、独自の名前とtearOffオプションがあります。 設定を保存するには、別のものを作成します

辞書:

 dict set menuBarSettings 0 name mainMenuBar dict set menuBarSettings 0 tearOff 1
      
      





すぐにメニューバーからドロップダウンメニューのタイプにデータを追加します。

 option add *tearOff [dict get $menu-settings 0 "tearOff"]
      
      





また、トップメニューを有効または無効にする機能をユーザーに提供するとします。

 dict set userSettings 0 menuBar true
      
      





しかし、レンダリングでは少し時間がかかります。 GUI全体を手動で記述するのはあまり意味がありません。なぜなら、私たちの武器には非常に強力なツールがあり、キーとパラメーターで辞書を繰り返しソートしているからです。 メニュータイトルのメニューについては、辞書を作成します。

 dict set menuBarItems_ZeroLevel 0 name connectionItem dict set menuBarItems_ZeroLevel 0 text_item "Connection" dict set menuBarItems_ZeroLevel 1 name helpItem dict set menuBarItems_ZeroLevel 1 text_item "Help"
      
      





ここで、最初のレベルに格納される辞書を作成します(親パラメーターは、最初のレベルがバインドされるメニューヘッダーのIDを示します)。

 dict set menuBarItems_FirstLevel 0 parent 0 dict set menuBarItems_FirstLevel 0 label "Open" dict set menuBarItems_FirstLevel 0 command NONE dict set menuBarItems_FirstLevel 1 parent 0 dict set menuBarItems_FirstLevel 1 label "Editt" dict set menuBarItems_FirstLevel 1 command NONE dict set menuBarItems_FirstLevel 2 parent 0 dict set menuBarItems_FirstLevel 2 label "Exit" dict set menuBarItems_FirstLevel 2 command { exit; } dict set menuBarItems_FirstLevel 3 parent 1 dict set menuBarItems_FirstLevel 3 label "About" dict set menuBarItems_FirstLevel 3 command NONE dict set menuBarItems_FirstLevel 4 parent 1 dict set menuBarItems_FirstLevel 4 label "Help" dict set menuBarItems_FirstLevel 4 command NONE
      
      





メニューの標準構文は分析しませんが、どのチュートリアルでも確認できます。 メニューの「描画」アルゴリズムに直行してください。

 #  ,   ""    proc assembleMyMenu {} { # ,       ,             global userSettings global menuBarSettings global menuBarItems_ZeroLevel global menuBarItems_FirstLevel # ,        if {[dict get $userSettings 0 "menuBar"]==true} { # ,  , : #       ( ,       ""      menu .[dict get $menuBarSettings 0 "name"] #          . config -menu .[dict get $menuBarSettings 0 "name"] #   .         dict for {id info} $menuBarItems_ZeroLevel { # info -        . ,   id-      ,     with     : dict with info { #        name  menu-bar-items       menu-settings: menu .[dict get $menuBarSettings 0 "name"].$name #    .[dict get $menuBarSettings 0 "name"] add cascade -label $text_item -menu .[dict get $menuBarSettings 0 "name"].$name #        ,     menu-bar-items_first-level dict for {iter data} $menuBarItems_FirstLevel { dict with data { #      ,   - : if {$id==$parent} { #    -     .[dict get $menuBarSettings 0 "name"].$name add command -label $label -command $command } } } } } } }
      
      





プログラムの完全なコード:



 #Require main packages for work package require Tk # Data for non user settings dict set nonUserSettings 0 title "myPrograms" dict set nonUserSettings 0 minWidth 800 dict set nonUserSettings 0 minHeight 600 dict set nonUserSettings 0 resizableX 1 dict set nonUserSettings 0 resizableY 1 # Data for user settings dict set userSettings 0 menuBar true # Data for biuld menubar dict set menuBarSettings 0 name mainMenuBar dict set menuBarSettings 0 tearOff 1 # Data for 0-level menu dict set menuBarItems_ZeroLevel 0 name connectionItem dict set menuBarItems_ZeroLevel 0 text_item "Connection" dict set menuBarItems_ZeroLevel 1 name helpItem dict set menuBarItems_ZeroLevel 1 text_item "Help" # Data for 1-level menu dict set menuBarItems_FirstLevel 0 parent 0 dict set menuBarItems_FirstLevel 0 label "LogIn" dict set menuBarItems_FirstLevel 0 command NONE dict set menuBarItems_FirstLevel 1 parent 0 dict set menuBarItems_FirstLevel 1 label "LogOut" dict set menuBarItems_FirstLevel 1 command NONE dict set menuBarItems_FirstLevel 2 parent 0 dict set menuBarItems_FirstLevel 2 label "Exit" dict set menuBarItems_FirstLevel 2 command { exit; } dict set menuBarItems_FirstLevel 3 parent 1 dict set menuBarItems_FirstLevel 3 label "About" dict set menuBarItems_FirstLevel 3 command NONE dict set menuBarItems_FirstLevel 4 parent 1 dict set menuBarItems_FirstLevel 4 label "Help" dict set menuBarItems_FirstLevel 4 command NONE # Procedure for builing menu bar proc assembleMyMenu {} { global userSettings global menuBarSettings global menuBarItems_ZeroLevel global menuBarItems_FirstLevel if {[dict get $userSettings 0 "menuBar"]==true} { menu .[dict get $menuBarSettings 0 "name"] . config -menu .[dict get $menuBarSettings 0 "name"] dict for {id info} $menuBarItems_ZeroLevel { dict with info { menu .[dict get $menuBarSettings 0 "name"].$name .[dict get $menuBarSettings 0 "name"] add cascade -label $text_item -menu .[dict get $menuBarSettings 0 "name"].$name dict for {iter data} $menuBarItems_FirstLevel { dict with data { if {$id==$parent} { .[dict get $menuBarSettings 0 "name"].$name add command -label $label -command $command } } } } } } } # Main programm logic # Window Manager main settings wm title . [dict get $nonUserSettings 0 "title"] wm resizable . [dict get $nonUserSettings 0 "resizableX"] [dict get $nonUserSettings 0 "resizableY"] wm minsize . [dict get $nonUserSettings 0 "minWidth"] [dict get $nonUserSettings 0 "minHeight"] option add *tearOff [dict get $menuBarSettings 0 "tearOff"] assembleMyMenu
      
      







レッスン/記事がお役に立てば幸いです。 常習者のtcl / tkコードに飛び込みましょう!



All Articles