|
|
TkDocs_Tk Tk Concepts. |
H.Kamifuji . |
あなたの背後にある最初の例では、Tk プログラムの外観と達成するために必要なタスクの種類に関する基本的な考え方が必要です。 ここでは、widgets 、geometry 管理、event 処理など、Tkを理解するために知っておく必要がある3つの広い概念を取り上げます。 |
Widgets は、あなたが画面上に見るすべてのものです。 この例では、button 、entry 、label 、および frame がありました。 他には、checkboxes 、tree views、scrollbars、textarea などがあります。 Widgets はしばしば「controls」と呼ばれます。 特に Tk のドキュメンテーションでは、X11 ルーツからのホールドオーバー(そのような用語の下では、トップレベルのウィンドウとボタンのようなものはウィンドウと呼ばれるでしょう)を「windows」と呼ぶことがよくあります。 ここではTkのウィジェットのいくつかを示していますが、これについては後で個別に説明します。 ![]() |
ウィジェットは、オブジェクト、ボタン、フレームなどを表すクラスのインスタンスです。 最初に行う必要があるのは、インスタンス化したいウィジェットの特定のクラスを特定することです。 このチュートリアルとウィジェットのまとめはそれを助けます。 |
あなたが知る必要があるもう一つのことは、作成したいウィジェットインスタンスの親です。 Tk では、すべてのウィジェットはウィンドウ階層の一部であり、階層の最上部に単一のルートがあります。 この階層は、任意に深いことができます。 そのため、ルートウィンドウ内の別のフレームのフレームにボタンが表示されることがあります。 新しいトップレベルウィンドウであっても、同じ階層の一部であり、そ のすべてのコンテンツが全体のウィンドウ階層のサブツリーを形成します。 メトリック変換の例では、ルートウィンドウの子として作成された単一のフレームがあり、そのフレームには他のすべてのコントロールが子として保持されていました。 ルートウィンドウはフレームのコンテナでしたので、フレームの親でした。 この例の完全な階層は、次の>ようになります。 ![]() |
すべてのウィジェットには、さまざまな設定オプションがあり、表示方法や動作方法を一般的に制御します。 使用可能なオプションはもちろんウィジェットクラスに依存します。異なるウィジェットクラス間には多くの一貫性があるため、同じことをするオプションは同じ名前になる傾向があります。したがって、ボタンとラベルの両方にウィジェットが表示するテキストを調整するための「テキスト」オプションがありますが、スクロールバーは不要なので「テキスト」オプションはありません。同じように、ボタンには押したときに何をすべきかを示す「コマンド」オプションがあり、静的なテキストだけを保持するラベルには表示されません。 設定オプションは、ウィジェットが最初に作成されたときにオプションの名前と値をオプションのパラメータとして渡すことで設定できます。後でそれらのオプションの価値が何であるかを確認することができ、非常に少数の例外を除いていつでもそれらを変更することができます。あなたがウィジェットのすべてのオプションが何であるかわからない場合は、ウィジェットにそれを提供するように頼むことができます。これにより、すべてのオプションの長いリストが表示され、オプションごとにオプションの名前と現在の値(通常は気にする必要のない3つの属性)が表示されます。 これは、インタプリタとの以下のインタラクティブなダイアログで最もよく説明されています。 Windows10 で、実行しました。 PS > python Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from tkinter import * >>> from tkinter import ttk >>> root = Tk() >>> button = ttk.Button(root, text="Hello", command="buttonpressed") >>> button.grid() >>> button['text'] 'Hello' >>> button['text'] = 'goodbye' >>> button.configure(text='goodbye') >>> button['text'] 'goodbye' >>> button.configure('text') ('text', 'text', 'Text', '', 'goodbye') > button.configure() {'command': ('command', 'command', 'Command', '', 'buttonpressed'), 'default': ('default', 'default', 'Default', <index object: 'normal'>, xi<<index object: 'normal'>), 'takefocus': ('takefocus', 'takeFocus', 'TakeFocus', 'ttk::takefocus', 'ttk::takefocus'), 'text': ('text', 'text', 'Text', '', 'goodbye'), 'textvariable': ('textvariable', 'textVariable', 'Variable', '', ''), 'underline': ('underline', 'underline', 'Underline', -1, -1), 'width': ('width', 'width', 'Width', '', ''), 'image': ('image', 'image', 'Image', '', ''), 'compound': ('compound', 'compound', 'Compound', <index object: 'none'>, <index object: 'none'>), 'padding': ('padding', 'padding', 'Pad', '', ''), 'state': ('state', 'state', 'State', <index object: 'normal'>, xi<<index object: 'normal'>), 'cursor': ('cursor', 'cursor', 'Cursor', '', ''), 'style': ('style', 'style', 'Style', '', ''), 'class': ('class', '', '', '', '') } >>> quit() PS > |
ウィジェットを作成して遊んでいる人は、ウィジェットを作成するだけで画面上に表示されないことに気づいたでしょう。画面上のウィンドウに実際に配置されたものを、ウィンドウ内のどこに表示するのかは、ジオメトリ管理と呼ばれる別のステップです。 この例では、この配置は "grid"コマンドによって実行されました。ここでは、各ウィジェットが必要とする列と行、グリッド内のアライメント方法などを渡しました。グリッドはジオメトリマネージャの一例です(そのうちのいくつかがTkにあり、グリッドが最も便利です)。グリッドについては後の章で詳しく説明しますが、ここでは一般的にジオメトリ管理について説明します。 ジオメトリ・マネージャーの仕事は、それらのウィジェットがどこに置かれるかを正確に把握することです。これは非常に困難な最適化問題であることが判明し、優れたジオメトリマネージャは非常に複雑なアルゴリズムに依存しています。優れたジオメトリマネージャは、プログラマを幸せにする柔軟性、使いやすさ、使いやすさを提供し、Tk の「グリッド」は間違いなく最高のものです。ジオメトリマネージャーが貧弱です...「GridBagLayout」で苦しんだ Java プログラマーは、すべて手を挙げてください。 |
ジオメトリマネージャの問題は、プログラムが作成するすべての異なるウィジェットと、ウィジェット内のどこにプログラムを移動させるか(他のウィジェットと比べて明示的に、またはより頻繁に)を指示することです。窓の中で その際、ジオメトリ・マネージャはいくつかの異なる制約のバランスをとる必要があります。
|
Tk のジオメトリ管理は、マスターウィジェットとスレーブウィジェットの概念に依存しています。マスターはウィジェット、典型的にはトップレベルウィンドウまたはフレームであり、スレーブと呼ばれる他のウィジェットを含む。ジオメトリ・マネージャは、マスター・ウィジェットを制御し、その中に表示されるものを決めると考えることができます。 ジオメトリマネージャーは、各スレーブウィジェットに対して自然なサイズ、または表示するのが理想的な大きさを尋ねます。その後、ジオメトリ・マネージャに特定のスレーブ・ウィジェットを管理するように要求されたときに、その情報を取得し、プログラムによって提供される任意のパラメータと組み合わせます。この例では、グリッドにグリッドを渡して、ウィジェットの相対位置を他のウィジェットに対して示した「ウィジェット」と、ウィジェットをどのように並べるべきかを示唆する「固定」パラメータを渡しました伸ばされた。また、「columnconfigure」と「rowconfigure」を使用して、ウィンドウに余分なスペースがある場合に展開したい列と行を示しました。もちろん、これらのパラメータはすべてグリッドに固有のものです。他のジオメトリ・マネージャは異なるものを使用します。 ジオメトリマネージャは、スレーブに関するすべての情報とマスターの大きさに関する情報を取得し、内部アルゴリズムを使用して各スレーブが割り当てられる領域(存在する場合)を決定します。スレーブはその特定の矩形内の描画などを行います。もちろん、マスターのサイズが変更されると(たとえば、トップレベルウィンドウがサイズ変更されたため)、スレーブの自然なサイズが変更されます(たとえば、ラベル内のテキストが変更されたため)。ジオメトリマネージャのパラメータ(例えば、「行」、「列」、または「粘着性」のように)変更すると、すべてを繰り返す。 これはすべて再帰的にも機能します。この例では、トップレベルウィンドウの内側にコンテンツフレームがあり、コンテンツフレームには他のいくつかのコントロールがあります。したがって、ジオメトリマネージャは2つの異なるマスターで作業していました。外側のレベルでは、トップレベルウィンドウがマスターであり、コンテンツフレームがスレーブでした。内側のレベルでは、コンテンツフレームがマスターであり、他のウィジェットのそれぞれはスレーブであった。したがって、同じウィジェットはマスターとスレーブの両方になることができます。この階層はもちろん、より深く入れ子にすることもできます。 各マスターは1つのジオメトリマネージャ(グリッドなど)しか持てませんが、異なるマスターには異なるジオメトリマネージャがある可能性があります。グリッドは一般的に使用されていますが、ユーザーインターフェイスの一部で使用されている特定のレイアウトには意味をなさないものもあります。また、私たちは、スレーブウィジェットがウィジェット階層のマスターの直下の子であるという前提を作りました。これは通常の場合ですが、ほとんどの場合、他の方法で行う必要はほとんどありません。いくつかの制限がありますが、これを回避することも可能です。 |
Tkでは、他のほとんどのユーザーインターフェイスツールキットと同様に、オペレーティングシステムからイベントを受け取るイベントループがあります。 これらは、ボタンの押下、キーストローク、マウスの移動、ウィンドウのサイズ変更などです。 一般的に、Tkはこのイベントループを管理します。 イベントが適用されるウィジェット(ユーザーがこのボタンをクリックしたかどうか、キーが押された場合、どのテキストボックスにフォーカスがあったかなど)を調べ、それに応じてディスパッチします。 個々のウィジェットはイベントへの対応方法を知っているので、マウスの上を移動するとボタンの色が変わり、マウスが離れると元に戻ることがあります。 |
Tk では、他のほとんどのユーザーインターフェイスツールキットと同様に、オペレーティングシステムからイベントを受け取るイベントループがあります。これらは、ボタンの押下、キーストローク、マウスの移動、ウィンドウのサイズ変更などです。 一般的に、Tk はこのイベントループを管理します。イベントが適用されるウィジェット(ユーザーがこのボタンをクリックしたかどうか、キーが押された場合、どのテキストボックスにフォーカスがあったかなど)を調べ、それに応じてディスパッチします。個々のウィジェットはイベントへの対応方法を知っています。たとえば、ボタンが押されたときに何かをするなど、プログラムが特定のイベントを処理したい場合でも、カスタマイズするのに非常に重要なイベント(ボタンを押したときに何も起こらないボタンは何ですか?)では、ウィジェットはウィジェットの設定オプションとしてコールバックを提供します。この例では、ボタンの「コマンド」オプションを使用しています。 Tk のコールバックは、コンパイルされた言語で使用されるツールキット(コールバックは、一般に、特定のパラメータセットを持つプロシージャまたは特定のシグネチャを持つオブジェクトメソッドを使用しなければならない)より簡単です。代わりに、コールバックは通訳が評価するコードの単なる普通のビットです。コールバックが他のいくつかのプロシージャを呼び出すようにしたいのですが、ほとんどの場合は複雑にすることもできますが、ほとんどの場合、その上を移動し、マウスが離れると元に戻ります。 |
関連するコマンドコールバックを持たないイベントについては、Tk の "bind" を使用して任意のイベントを取得し、コールバックのように任意のコードを実行できます。 ラベルに表示される内容を変更するだけで、ラベルが異なるイベントに応答するようにバインディングを設定する方法を示す(ばかげた)例を次に示します。 Code ( perl Tkx ) use Tkx; my $mw = Tkx::widget->new("."); (my $l = $mw->new_ttk__label(-text => "Starting..."))->g_grid; $l->g_bind(" Code ( Python ) from tkinter import * from tkinter import ttk root = Tk() l =ttk.Label(root, text="Starting...") l.grid() l.bind('<Enter>', lambda e: l.configure(text='Moved mouse inside')) l.bind('<Leave>', lambda e: l.configure(text='Moved mouse outside')) l.bind('<1>', lambda e: l.configure(text='Clicked left mouse button')) l.bind('<Double-1>', lambda e: l.configure(text='Double clicked')) l.bind('<B3-Motion>', lambda e: l.configure(text='right button drag to %d,%d' % (e.x, e.y))) root.mainloop()最初の 3 つのイベントバインディングは単純なイベントを見るだけでかなり簡単です。ダブルクリックバインディングは、イベント修飾子の考え方を導入します。この場合、マウスの左クリック(「1」)でイベントをトリガーしたいが、ダブルクリック(「Double-」)のときにのみトリガーしたい。 最後のバインドでは、マウスの動きをキャプチャする(「モーション」)が、マウスの右ボタン(「B3」)が押されている場合にのみ、モディファイアが使用されます。このバインディングは、パーセント置換を使用してイベント・パラメーターを使用する方法の例も示しています。マウスのクリックや移動などの多くのイベントは、マウスの現在の位置などの追加情報をパラメータとして持っています。これらのパーセント置換は、スクリプトで使用できるようにキャプチャさせます。 Tkx では、Perl 関数(最初の 4 つ)として、または 2 つの要素配列(最後のケース)としてコマンドコールバックを提供できます。最初の要素は呼び出される Perl コードで、2 番目の配列要素はそのコードに渡すパラメータを指定します。関数 "Tkx :: Ev()"は、コールバックが呼び出されたときにそのパラメータ(この場合は "%x%y")を展開し、パーセント置換を実行します。これらはパラメータとして関数に渡されます。 Tkinter では、イベントコールバックとしての関数を提供することを期待しています。最初の引数は、コールバックをトリガしたイベントを表すイベントオブジェクトです。この例のような一回限りのコールバックのための通常の名前付き関数を定義するのは大して価値がありません。だから、私たちはラムダ経由でPythonの無名関数を使っただけです。初期のフィート・トゥ・フィートの例では、定期的に定義された関数(計算)を使用しました。 すべての異なるイベント名、修飾子、およびそれぞれで使用可能なさまざまなイベントパラメータの完全な説明については、「バインド」コマンドリファレンスを参照するのが最適です。 |
マウスクリックやウィンドウのサイズ変更などの低レベルのオペレーティングシステムイベント以外にも、多くのウィジェットは仮想イベントと呼ばれるより高いレベルのイベントを生成します。 例えば、リストボックスウィジェットは、ユーザーがアイテムをクリックしたか、矢印キーで移動したのか、それとも何にでも関係なく、選択が変更されたときにいつでも、 "ListboxSelect" 仮想イベントを生成します。 これにより、複数の、場合によってはプラットフォーム固有のイベント・バインディングを設定して変更をキャプチャする問題を回避できます。 ウィジェットの仮想イベントがあれば、それがウィジェットのドキュメントにリストされます。 |
ウィジェットは実際には、単一のイベントに対して多数の異なるイベントバインディングをトリガすることができます。 通常、イベントは、個々のウィジェット自体、特定のクラスのすべてのウィジェット(ボタンなど)、ウィジェットを含むトップレベルウィンドウ、およびアプリケーション内のすべてのウィジェットに対して設定できます。 これらはそれぞれ順番に発射されます。 この例では、トップレベルウィンドウの Return キーとそのウィンドウ内のすべてのウィジェットに適用される戻り値のバインドを設定するときにこれを確認しました。 Tk の各ウィジェットクラスのデフォルトの動作自体は、スクリプトレベルのイベントバインディングで定義されているため、イントロスペクトされ、特定のクラスのすべてのウィジェットの動作を変更することができます。 ウィジェットごとに、この一連のイベントの処理を完 全に変更することもできます。 興味がある場合は、 "bindtags" コマンドリファレンスを参照してください。 |
Tk Concepts |
|