3

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

目标图形用户界面:

目标图形用户界面

到目前为止,这就是我的 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()
4

3 回答 3

7

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

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

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

看起来您已经有了联系表单的布局,所以将它们移动到右上角的框架中。确保在您扩大和缩小窗口时它们都正确扩大和缩小(因此,您扩大和缩小包含框架)。

完成此操作后,请继续下一部分 - 将联系人列表放在左上角。再次,确保它都正确调整大小。此时,您不必担心右侧的小部件,因为您已经整理好了这些小部件。对于本节,您不需要网格,您可以使用 pack,因为它只是几个堆叠在一起的小部件。但是,您可以使用最有意义的方法。

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

于 2013-05-01T11:19:37.747 回答
4

我做了类似的事情,检查一下:

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()  
于 2014-01-25T07:44:17.960 回答
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()。无论如何,我会尽量不混合它们中的任何一个。

关于主要问题'你如何设置网格的位置',好吧,试着在纸上画出你期望的东西,然后试着把它分成行和列......

于 2013-05-01T09:54:34.520 回答