7

私の苦情

私は現在、Tkinter GUIをこれまでよりも深く掘り下げていますが.grid()、いくつかの理由でジオメトリマネージャーが不十分であることがわかりました。

  1. プロットは、その中の最大のウィジェットに基づいています-この相対性理論は不正確さにつながります。

  2. Windows 7、Python 2.7.3では、プログラムは私の行番号に注意を払っていないようで、代わりにウィジェットの順序を使用することを好みます。

私のコード

私は現在、非常に基本的なテキストエディタに取り組んでおりフレームの上部に複数のボタンを配置したいと考えています。ウィジェットが画面の中央を占める巨大なテキストボックスの左端または右端に配置されているため、これを行うことができませんでした。

========Class __init__ Stuff============
def widget(self):#Place widgets here

    #Save Button
    self.saveButton = Button (self, text = "Save", command = self.saveMe)
    self.saveButton.grid(column = 0, row = 0, sticky = W)

    #Open Button
    self.openButton = Button (self, text = "Open", command = self.openMe)
    self.openButton.grid(column = 0, row = 1, sticky = W)
    #Area where you write 
    self.text = Text (self, width = (root.winfo_screenwidth() - 20),
                      height = (root.winfo_screenheight() - 10))
    self.text.grid(row = 2)
==============Mainloop/Command Stuff============

私の質問

.grid()より正確な方法でジオメトリマネージャーを使用する別の方法はありますか、それとも別の関数を完全に使用する必要がありますか?

ありがとう!

4

4 に答える 4

16

使用できるジオメトリマネージャは3つあります- grid、、。3つ目は最も一般的ですが、使用するのも非常に困難です。私は好きです。ウィジェットを他のウィジェット内に配置できることに注意してください-または、を指定できます。したがって、次のレイアウトを取得する場合:packplacegridcolumnspan

  -------------------------
  |    Button1  | Button2 |
  -------------------------
  |     Big Widget        |
  -------------------------

を使用してそれを行うための2つの標準的な方法があります.grid。最初の方法はcolumnspan次のとおりです。

import Tkinter as Tk
root = Tk.Tk()
b1 = Tk.Button(root,text="Button1")
b1.grid(row=0,column=0)
b2 = Tk.Button(root,text="Button2")
b2.grid(row=0,column=1)
big_widget = Tk.Canvas(root)
big_widget.grid(row=1,column=0,columnspan=2)

rowspan*完全に類似したオプションもあることに注意してください。

2番目の方法は、を使用しFrameてボタンを保持することです。

import Tkinter as Tk
root = Tk.Tk()
f = Tk.Frame(root)
f.grid(row=0,column=0)
#place buttons on the *frame*
b1 = Tk.Button(f,text="Button1")
b1.grid(row=0,column=0)
b2 = Tk.Button(f,text="Button2")
b2.grid(row=0,column=1)

big_widget = Tk.Canvas(root)
big_widget.grid(row=1,column=0)  #don't need columnspan any more.

この方法は、複雑なレイアウトを作成するのに非常に便利Frameです。このようなオブジェクトを使用せずに複雑なレイアウトを作成する方法がわかりません...

于 2013-02-13T03:54:52.077 に答える
7

「最適な」ジオメトリマネージャは、実行する内容によって異なります。すべての状況に最適なジオメトリマネージャはありません。この特定のケースで何をしようとしているのかについては、おそらくパックがより良い選択です。また、アプリケーションには複数の「最良」が存在する可能性があることにも注意してください。アプリケーションのさまざまな部分でグリッドとパックの両方を使用するのはごく普通のことです。グリッドとパックの両方を使用しないGUIを作成することはめったにありません。そしてめったに、私も場所を使いません。

packは、単一の行と単一の列に物を配置するのに優れています。たとえば、ツールバーは、すべてのボタンを左に揃えたいので、パックを使用するのに最適なケースです。グリッドは、その名前が示すように、固定の行と列が必要な場合に最適です。placeは、ウィジェットを正確な固定位置または相対位置に配置できるため、グリッドもパックも機能しないまれなケースで役立ちます。

私のアドバイスは、アプリケーションウィジェットをグループに分割し、各グループに適切なジオメトリマネージャーを使用することです。あなたの場合、2つの論理グループがあります。上部にあるツールバーと下部にあるテキスト-ウィジェットとスクロールバーの組み合わせです。したがって、2つのフレームから始めます。ツールバーが上にあり、テキストウィジェットが下にあるため、packが最適に機能します。

toolbar = tk.Frame(...)
main = tk.Frame(...)
toolbar.pack(side="top", fill="x", expand=False)
main.pack(side="bottom", fill="both", expand=True)

上記により、個別に変更するのが簡単な2つの領域が得られます。

ツールバーの場合、パックはやはり最も自然です。ただし、この場合、ボタンは上部または下部ではなく左側に配置する必要があります。

b1 = tk.Button(toolbar, ...)
b2 = tk.Button(toolbar, ...)
b1.pack(side="left")
b2.pack(side="left")
...

最後に、下部の領域。サンプルコードにはスクロールバーが表示されていませんが、ある時点でスクロールバーを追加したいと思います。水平スクロールバーと垂直スクロールバーの両方を使用している場合、グリッドは適切に機能します。私はそれらをこのようにレイアウトします:

hsb = tk.Scrollbar(main, ..., orient="horizontal", ...)
vsb = tk.Scrollbar(main, ..., orient="vertical", ...)
text = tk.Text(main, ...)
vsb.grid(row=0, column=1, sticky="ns")
hsb.grid(row=1, column=0, sticky="ew")
text.grid(row=0, column=0, sticky="nsew")
main.grid_rowconfigure(0, weight=1)
main.grid_columnconfigure(0, weight=1)

その最後の部分は重要です。少なくとも1つの行と1つの列に常に重みを付ける必要があります。これは、ウィンドウのサイズが変更されたときにどの行と列を拡大および縮小するかをグリッドに指示します。

于 2013-02-13T12:24:14.193 に答える
1

place位置とサイズの両方に絶対長と相対長の組み合わせを指定できるため、マネージャーは3つすべての中で最も直感的で正確 だと思います。

mywidget.place(x=..., y=..., width=..., height=...) # absolute
mywidget.place(relx=..., rely=..., relwidth=..., relheight=...) # relative

# combination
pad_left=5
pad_right=5
pad_top=5
pad_bottom=5
mywidget.place(relx=0, x=pad_left, rely=0, y=pad_top,\
       relwidth=1, width=-pad_left-pad_right,\
       relheight=1, height=-pad_top-pad_bottom, anchor="e") # use the whole space except some padding

何らかの理由で、.placeマネージャーはあまり好まれていないようですが、親ウィンドウのサイズが変更されたときにウィジェットがどのように移動してサイズを変更するかを定義することは特に良い仕事だと思います。

複雑なウィンドウの作成を容易にするために、次のような垂直配置を支援する関数(グリッドの動作をエミュレートするため)を使用することがあります。

def offset_y(line_no):
    if line_no == 0:
        return 0
    else:
        return height_label + (line_no - 1)*height_button

mylabel.place(..., y=offset_y(0))
mybtn1.place(..., y=offset_y(1))
etc.

ラベルを縦に詰めてから、一連のボタンを詰めます。(もちろん、.packこの場合はマネージャーを使用できますが、私がマネージャーを好む理由は.place、ウィンドウのサイズが変更されたときに物事がどのように動くかをより正確に理解するためです)。

于 2013-04-06T15:32:33.693 に答える
-2

行、列などの代わりに、座標を使用できます。

他のものより簡単かもしれません。

例:

from Tkinter import*
root=Tk()
Button(root,text="HI").grid(padx=100,pady=50)
root.mainloop()

padxとpadyの値を変更して、自分で試してみてください。

于 2017-03-10T07:16:20.730 に答える