2013-05-01 132 views
2

甚至可以在Tkinter中设置网格的绝对位置吗?我正在尝试创建一个类似于下图的GUI,但我可能会以错误的方式进行操作。所以如果可能的话,你如何设置网格位置?如何使用Tkinter设置网格的位置?

目标GUI:

Target GUI

这是我的GUI是如何转向了,至今:

My GUI

正如你看到的,我的新联系人必须在对,而联系人列表应该在左边。我知道如何使用绝对值来移动联系人列表,但我可以对我的网格元素执行相同的操作吗?或者我应该使用所有这些绝对值,并结合填充?

目前,这是我的代码:

from tkinter import * 
contacts=['Justin Day'] 

class Contact_manager (Frame): 

    def __init__(self, parent): 
     Frame.__init__(self, parent) 

     self.parent = parent 
     self.initUI() 

    def initUI(self): 
     self.parent.title("Contact Manager") 
     self.pack(fill=BOTH, expand=1) 

     #New contact grid 
     Label (self, text = "New Contact").grid (row=0, columnspan=2) 
     Label (self, text = "First Name:").grid (row=1, sticky=E) 
     Label (self, text = "Last Name:").grid (row=2, sticky=E) 
     Label (self, text = "Phone#").grid (row=3, sticky=E) 

     self.entry1 = Entry(self) 
     self.entry2 = Entry(self) 
     self.entry3 = Entry(self) 
     self.entry1.grid (row=1, column=1) 
     self.entry2.grid (row=2, column=1) 
     self.entry3.grid (row=3, column=1) 

     friend_check = IntVar() 
     self.friend_check = Checkbutton (self, variable = friend_check, 
           command = self.friend_box, 
           text = "Friend") 
     self.friend_check.grid (row=4, columnspan=2) 

     Label (self, text = "Email:").grid (row=5, sticky=E) 
     Label (self, text = "Birthday:").grid (row=6, sticky=E) 

     self.entry4 = Entry(self) 
     self.entry5 = Entry(self) 
     self.entry4.grid (row=5, column=1) 
     self.entry5.grid (row=6, column=1) 

     #Contact listbox 
     Label (self, text = "Contact List").place(x=20, y=190) 
     contact_lb = Listbox(self) 
     for i in contacts: 
      contact_lb.insert(END, i) 

     contact_lb.bind("<<ListboxSelect>>", self.onSelect) 
     contact_lb.place(x=20, y=210) 

    def onSelect(self, val): 

     sender = val.widget 
     idk = sender.curselection() 
     value = sender.get(idx) 

     self.var.set(value) 

    def friend_box(): 
     if friend_check.get() == 1: 
      contacts.append(Friend(f, l, p, e, bd)) 
     else: 
      contacts.append(Person(f, l, p)) 
def main(): 

    root = Tk() 
    ex = Contact_manager(root) 
    root.geometry('600x700+200+100') 
    root.mainloop() 

if __name__ == '__main__': 
    main() 

回答

5

你应该采取在GUI中布置小部件的分而治之的方法。不要试图一次做所有事情,或者使用一个几何管理器在一个窗口中协调一切。要有条不紊,一次解决一个小问题。

例如,在您的目标GUI中,看起来您有四个部分:联系人列表,搜索框和按钮,新联系人表单以及右下角(搜索结果?)中的内容。如果我认为这些是四个不同的领域,那么首先创建四个框架。使用网格将它们放置在主窗口的四个角落。给每个框架一个不同的颜色(用于调试目的)。现在,摆弄这些选项,直到这四个区域以您想要的方式增长和缩小。确保你给列和行的权重,以便他们都适当调整大小。

现在你已经做到了,你有四个更小,更易于管理的布局问题。现在,这可能是我错了 - 也许你有两个区域,左侧和右侧。或者,也许你有三个 - 左边,然后右上和右下。现在我们假设我是对的,但技术保持不变。

看起来你已经有了联系表单的布局,所以把它们移到右上角的框架中。确保当你长大和缩小窗口时,它们都能正确展开和收缩(因此,你可以增长和缩小包含的框架)。

一旦你完成了,在下一部分工作 - 把联系人列表在左上角。再次确保它全部调整正确。此时,您不必担心右侧的小部件,因为您已经完成了这些小部件。对于本节你不需要grid,你可以使用pack,因为它只是堆叠在一起的几个小部件。但是,您可以使用最合理的方式。

继续这种方式,在GUI的剩余两个角上工作。有条不紊,一次处理一个小的独立部分。

+1

谢谢!我喜欢你如何解释这些方法去做事情,以便我能够理解如何彻底打破它。创建多个框架时,创建每个框架作为方法还是作为单独的类创建更好?哪种更加Pythonic?谢谢。 – 2013-05-01 18:18:39

2

下面是一些看起来更接近你所需要的:

from tkinter import * 
contacts=['Justin Day'] 

class Contact_manager (Frame): 

    def __init__(self, parent): 
     Frame.__init__(self, parent) 

     self.parent = parent 
     self.initUI() 

    def initUI(self): 
     self.parent.title("Contact Manager") 
     self.pack(fill=BOTH, expand=1) 

     #New contact grid 
     Label (self, text = "New Contact").grid (row=0, column=2, columnspan=2, sticky=W) 
     Label (self, text = "First Name:").grid (row=1, column=1, sticky=E) 
     Label (self, text = "Last Name:").grid (row=2, column=1, sticky=E) 
     Label (self, text = "Phone#").grid (row=3, column=1, sticky=E) 

     self.entry1 = Entry(self) 
     self.entry2 = Entry(self) 
     self.entry3 = Entry(self) 
     self.entry1.grid (row=1, column=2) 
     self.entry2.grid (row=2, column=2) 
     self.entry3.grid (row=3, column=2) 

     friend_check = IntVar() 
     self.friend_check = Checkbutton (self, variable = friend_check, 
           command = self.friend_box, 
           text = "Friend") 
     self.friend_check.grid (row=4, column=2, columnspan=2) 

     Label (self, text = "Email:").grid (row=5, column=1, sticky=E) 
     Label (self, text = "Birthday:").grid (row=6, column=1, sticky=E) 

     self.entry4 = Entry(self) 
     self.entry5 = Entry(self) 
     self.entry4.grid (row=5, column=2) 
     self.entry5.grid (row=6, column=2) 

     #Contact listbox 
     Label (self, text = "Contact List").grid(row=0) 
     contact_lb = Listbox(self) 
     for i in contacts: 
      contact_lb.insert(END, i) 

     contact_lb.bind("<<ListboxSelect>>", self.onSelect) 
     contact_lb.grid(row=1, rowspan=5) 

    def onSelect(self, val): 

     sender = val.widget 
     idk = sender.curselection() 
     value = sender.get(idx) 

     self.var.set(value) 

    def friend_box(): 
     if friend_check.get() == 1: 
      contacts.append(Friend(f, l, p, e, bd)) 
     else: 
      contacts.append(Person(f, l, p)) 
def main(): 

    root = Tk() 
    ex = Contact_manager(root) 
    root.geometry('600x700+200+100') 
    root.mainloop() 

if __name__ == '__main__': 
    main() 

我不知道你是否应该混合.grid()和.place(),据我所知,你不应该混合使用.pack()和.grid()。无论如何,我会尽量不要混合其中的任何一个。

而关于主要问题“你怎么设置网格的位置”,那么,就试着画出你期望在纸上的东西,并试图将其分为行和列...

+1

你永远不应该在同一个容器中混合电网和包装,但它是相当正常的在同一应用程序同时使用。使用地方相当不寻常。 – 2013-05-01 11:08:15

2

我没有类似的东西,检查出来:

from Tkinter import Tk, N, S, W, E, BOTH, Text, Frame,Label, Button,Checkbutton, IntVar,Entry 


class Example(Frame): 

    def __init__(self, parent): 
     Frame.__init__(self, parent) 
     self.parent = parent 
     self.initUI() 

    def initUI(self):  
     self.parent.title("Windows") 


     Label(text="Contact List").grid(row=0,column=0,columnspan=2) 
     Text(width=30,height=15).grid(row=1,rowspan=9, column=0,columnspan=2,padx=20) 
     Button(text="Display Contact").grid(row=10, column=0,columnspan=2,pady=10) 
     Label(text="Last Name:").grid(row=11, column=0,pady=10) 
     Entry().grid(row=11,column=1) 
     Button(text="Search").grid(row=12,column=0,columnspan=2) 



     Label(text="New Contact").grid(row=0,column=2,columnspan=2) 
     Label(text="First Name:").grid(row=1,column=2,sticky=E) 
     Entry().grid(row=1,column=3) 
     Label(text="Last Name:").grid(row=2,column=2,sticky=E) 
     Entry().grid(row=2,column=3) 
     Label(text="Phone #:").grid(row=3,column=2,sticky=E) 
     Entry().grid(row=3,column=3) 
     friend_check = IntVar() 
     Checkbutton(variable=friend_check, command = self.friend_box, text = "Friend").grid(row=4,column=3,sticky=W) 
     #Label(text="Friend").grid(row=4,column=3,padx=20,sticky=W) 
     Label(text="Email:").grid(row=5,column=2,sticky=E) 
     Entry().grid(row=5,column=3) 
     Label(text="Birthday:").grid(row=6,column=2,sticky=E) 
     Entry().grid(row=6,column=3) 
     Button(text="Add Contact").grid(row=7,column=3,sticky=E) 

    def friend_box(self): 
     if friend_check.get() == 1: 
      print '1' 
     else: 
      print '0' 


def main(): 

    root = Tk() 
    root.geometry("600x450+900+300") 
    root.resizable(0,0) 
    app = Example(root) 
    root.mainloop() 


if __name__ == '__main__': 
    main() 
相关问题