甚至可以在Tkinter中设置网格的绝对位置吗?我正在尝试创建一个看起来像下面的GUI,但我可能会采用错误的方式。所以如果可能的话,你如何设置网格位置?
目标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()
答案 0 :(得分:5)
您应该采用分而治之的方法在GUI中布置小部件。不要试图一次完成所有事情或使用一个几何管理器来协调一个窗口中的所有内容。要有条不紊,一次解决一个小问题。
例如,在您的目标GUI中,您会看到四个部分:联系人列表,搜索框和按钮,新的联系表单以及右下角的某些内容(搜索结果?)。如果我是正确的,那是四个不同的区域,首先创建四个框架。使用网格将它们放在主窗口的四个角上。为每个帧提供不同的颜色(用于调试目的)。现在,摆弄选项,直到这四个领域以您想要的方式增长和缩小。确保给出列和行的权重,以便它们都能正确调整大小。
现在您已经完成了这项工作,您有四个更小,更易于管理的布局问题。现在,可能是我错了 - 也许你有两个区域,左和右。或者你可能有三个 - 左边,然后是右上角和右下角。现在我们假设我是对的但无论如何技术都是一样的。
看起来您已经拥有联系表单的布局,因此将它们移动到右上角框架中。当你长大并缩小窗口时,确保它们都能正确展开和收缩(因此,你可以使包含的框架生长和收缩)。
完成后,请继续操作下一部分 - 将联系人列表放在左上角。再次确保它们都正确调整大小。此时您不必担心右侧的小部件,因为您已经整理了这些小部件。对于本节,您不需要网格,您可以使用pack,因为它只是几个小部件堆叠在一起。但是,你可以使用最有意义的。
继续这样,继续处理GUI的剩余两个角落。要有条不紊,一次一个地处理小的独立部分。
答案 1 :(得分: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()。无论如何,我会尽量不混合任何一种。
关于主要问题'如何设置网格的位置',好吧,只是尝试在纸上绘制您期望的内容,并尝试将其划分为行和列...
答案 2 :(得分: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()