2014-11-23 66 views
0

在Mac OS上使用python 3.4.1我試圖在稱爲'lowerframe'的子框架中使用網格幾何管理器平均分配標籤和條目小部件。tkinter網格:在框架高度和寬度上分佈行和列

我現在MWE如下所示:

#!/usr/bin/env python3 

from tkinter import * 
from tkinter import ttk 

class Window(Frame): 
    def __init__(self, master=None): 
     Frame.__init__(self, master) 
     # create master window 
     self.master = master 

     # create root window on initialization 
     self.create_rootwindow() 

    def create_rootwindow(self): 
     self.master.title("GUI") 
     self.master.geometry("1024x748") 
     self.master.resizable(width=FALSE, height=FALSE) 

     self.create_upperframe() 
     self.create_lowerframe() 
     self.create_inputentries() 
     self.create_btnframe() 
     self.create_inputbtn() 

    def create_upperframe(self): 
     self.upperframe = Frame(self.master, width=980, height=490) 
     self.upperframe.config(background="#339900") 
     self.upperframe.place(x=20, y=10) 

    def create_lowerframe(self): 
     self.lowerframe = Frame(self.master, width=830, height=200) 
     self.lowerframe.config(background="#336699") 
     self.lowerframe.place(x=20, y=530) 

    def create_inputentries(self): 
     self.create_lowerframe() 

     parameternames = [ 
      ('a', 'U'), ('b', 'U'), ('c', 'U'), ('d', 'U'), ('e', 'U'), 
      ('f', 'U'), ('g', 'U'), ('h', 'U'), ('i', 'U'), ('j', 'U'), 
      ('k', 'U'), ('l', 'U'), ('m', 'U'), ('n', 'U'), ('o', 'U'), 
      ('p', 'U'), ('q', 'U'), ('r', 'U'), ('s', 'U'), ('t', 'U')] 

     for i, data in enumerate(parameternames): 
      r = i % 5 
      c = (i // 5) * 3 
      Label(self.lowerframe, text=data[0]).grid(row=r, column=c, pady=4, padx=0) 
      Entry(self.lowerframe, width=10).grid(row=r, column=c+1, pady=4, padx=0) 
      Label(self.lowerframe, text=data[1]).grid(row=r, column=c+2, pady=4, padx=0) 

    def create_btnframe(self): 
     self.btnframe = Frame(self.master, width=130, height=200) 
     self.btnframe.place(x=870, y=530) 

    def create_inputbtn(self): 
     self.create_btnframe() 

     startanalysis_btn = Button(self.btnframe, text="Start Analysis", width=12, command=self.do_nothing) 
     startanalysis_btn.place(x=0, y=0) 

     abortanalysis_btn = Button(self.btnframe, text="Abort Analysis", width=12, command=self.do_nothing) 
     abortanalysis_btn.place(x=0, y=50) 

     resetanalysis_btn = Button(self.btnframe, text="Reset Analysis", width=12, command=self.do_nothing) 
     resetanalysis_btn.place(x=0, y=100) 

     showresults_btn = Button(self.btnframe, text="Show Results", width=12, command=self.do_nothing) 
     showresults_btn.place(x=0, y=200, anchor=SW) 

    def do_nothing(self): 
     pass 

root = Tk() 

app = Window(root) 

root.mainloop() 

正如你所看到的,每個下部,藍框控件(稱爲「lowerframe」)的「設置」由一個標籤與說​​明書(這裏'a'到't'),一個輸入小部件和另一個標籤小部件,其輸入值的相應單位(這裏是所有標籤的'U')。

使用這些「集合」我需要創建五行和4個「設置列」(目前使用網格幾何管理器的12列)。我的目標是將這些行和「設置列」分配到指定高度和寬度的底框。

- 編輯:我上傳了sketch到我的Dropbox文件夾,顯示結果應該如何。

回答

2

您編寫代碼的方式使其很難修改。首先,根據經驗,你絕不應該使用place。根本沒有必要,因爲packgrid提供更多的功能。

其次,作爲一個經驗另一個規則,家長應該負責佈置其子 - 沒有,創建一個框架的功能也呼籲gridpack,或place把自己在其父。如果你決定改變你的佈局,你最終不得不改變一堆功能。

最後,當使用網格時,如果您希望它們增長以填充其包含的窗口,則需要給出行和列「重量」。

這是我會怎麼重寫代碼:

from tkinter import * 

class Window(Frame): 
    def __init__(self, master=None): 
     Frame.__init__(self, master) 
     # create master window 
     self.master = master 

     # create root window on initialization 
     self.create_rootwindow() 

    def create_rootwindow(self): 
     self.master.title("GUI") 
     self.master.geometry("1024x748") 

     self.create_upperframe() 
     self.create_lowerframe() 
     self.create_inputentries() 
     self.create_btnframe() 
     self.create_inputbtn() 

     self.upperframe.pack(side="top", fill="both", expand=True, padx=4) 
     self.lowerframe.pack(side="left", fill="both", expand=True, padx=4, pady=4) 
     self.btnframe.pack(side="right", fill="both", padx=4, pady=4) 

    def create_upperframe(self): 
     self.upperframe = Frame(self.master, width=980, height=490) 
     self.upperframe.config(background="#339900") 

    def create_lowerframe(self): 
     self.lowerframe = Frame(self.master, width=830, height=200) 
     self.lowerframe.config(background="#336699") 

    def create_inputentries(self): 
     self.create_lowerframe() 

     parameternames = [ 
      ('a', 'U'), ('b', 'U'), ('c', 'U'), ('d', 'U'), ('e', 'U'), 
      ('f', 'U'), ('g', 'U'), ('h', 'U'), ('i', 'U'), ('j', 'U'), 
      ('k', 'U'), ('l', 'U'), ('m', 'U'), ('n', 'U'), ('o', 'U'), 
      ('p', 'U'), ('q', 'U'), ('r', 'U'), ('s', 'U'), ('t', 'U')] 

     for i, data in enumerate(parameternames): 
      r = i % 5 
      c = (i // 5) * 3 
      Label(self.lowerframe, text=data[0]).grid(row=r, column=c, pady=4, padx=0, sticky="nsew") 
      Entry(self.lowerframe, width=10).grid(row=r, column=c+1, pady=4, padx=0, sticky="ew") 
      Label(self.lowerframe, text=data[1]).grid(row=r, column=c+2, pady=4, padx=0, sticky="nswe") 

      self.lowerframe.grid_columnconfigure(c+1, weight=1) 


    def create_btnframe(self): 
     self.btnframe = Frame(self.master, width=130, height=200) 

    def create_inputbtn(self): 
     self.create_btnframe() 

     startanalysis_btn = Button(self.btnframe, text="Start Analysis", width=12, command=self.do_nothing) 
     abortanalysis_btn = Button(self.btnframe, text="Abort Analysis", width=12, command=self.do_nothing) 
     resetanalysis_btn = Button(self.btnframe, text="Reset Analysis", width=12, command=self.do_nothing) 
     showresults_btn = Button(self.btnframe, text="Show Results", width=12, command=self.do_nothing) 

     startanalysis_btn.pack(side="top", fill="x") 
     abortanalysis_btn.pack(side="top", fill="x") 
     resetanalysis_btn.pack(side="top", fill="x") 
     showresults_btn.pack(side="top", fill="x") 

    def do_nothing(self): 
     pass 

root = Tk() 
app = Window(root) 
root.mainloop() 

事情需要注意:

  • 我已經更換了的place所有使用與pack(雖然grid將工作一樣好)
  • 我已將pack的主要區域分組在一起
  • 我將pack按鈕分組在一起,使得可視化和修改更容易。
  • 我已經爲底部框架中具有條目窗口小部件的列添加了權重。這會導致這些列增長或縮小以填充任何額外空間
  • 我已將設置可調整大小設置爲false。一般來說,我認爲應該允許用戶選擇GUI的大小。此外,它還說明通過使用pack和/或grid而不是place,您可以在不做任何額外工作的情況下獲得適當的調整行爲。如果您真的認爲自己比用戶更瞭解,那麼可以重新加入。

代碼現在具有良好的調整行爲,入口小部件的網格展開以填充其容器,並且功能耦合不太緊密因爲創建框架的功能不必知道框架將如何顯示。

+0

這解決了我的一半任務。小部件現在分佈在框架的高度和寬度上。不過,我想指定條目窗口小部件的寬度,並在每組「label-entry-label」之間獲得一些自動分配的空間。目前,我無法爲條目窗口部件指定寬度,或者至少在當前設置中不會生效。我上傳了一個[sketch](https://dl.dropboxusercontent.com/u/7203428/SO/lowerframe_sketch.png)到我的Dropbox文件夾,顯示我想要達到的效果 – albert 2014-11-23 17:50:35

+0

@albert:給予你想要的寬度具有明確的寬度,並且對要增長或縮小的列使用非零權重。這裏沒有魔法,這都是非常確定的。如果您希望可變寬度的_between_小部件,創建一個沒有任何小部件的列,併爲該列賦予權重。 – 2014-11-23 17:53:12