2015-12-14 13 views
9

My gui layoutTkinter gui bố trí sử dụng khung và lưới

gui layout

trông gần như không có gì what I expect

what I expect

vì vậy tôi giả định có một số vấn đề cơ bản mà tôi không hiểu.

Tôi giả định rằng các khung có chứa 'không gian lưới' riêng của họ (hàng, cột) nhưng hành vi mà tôi thấy không chịu được điều đó, và tôi đang thua lỗ để làm mọi thứ theo cách tôi muốn khung. Nhãn của tôi được cho là nằm trên cùng hàng L đến R, dưới 'nhãn khung' kéo dài toàn bộ khung - ngoại trừ chúng không. Tôi muốn thực tế trông giống như jpg mục tiêu hơn và tôi muốn sử dụng lưới để làm điều đó.

Bạn chỉ có thể thấy một trong các trường nhập ở bên phải của khung màu xanh lá cây. Tại sao nó lại đến đó?

from Tkinter import * 

root = Tk() 
root.title('Model Definition') 
root.resizable(width=FALSE, height=FALSE) 
root.geometry('{}x{}'.format(460, 350)) 

top_frame = Frame(root, bg='cyan', width = 450, height=50, pady=3).grid(row=0, columnspan=3) 
Label(top_frame, text = 'Model Dimensions').grid(row = 0, columnspan = 3) 
Label(top_frame, text = 'Width:').grid(row = 1, column = 0) 
Label(top_frame, text = 'Length:').grid(row = 1, column = 2) 
entry_W = Entry(top_frame).grid(row = 1, column = 1) 
entry_L = Entry(top_frame).grid(row = 1, column = 3) 
#Label(top_frame, text = '').grid(row = 2, column = 2) 

center = Frame(root, bg='gray2', width=50, height=40, padx=3, pady=3).grid(row=1, columnspan=3) 
ctr_left = Frame(center, bg='blue', width=100, height=190).grid(column = 0, row = 1, rowspan = 2) 
ctr_mid = Frame(center, bg='yellow', width=250, height=190, padx=3, pady=3).grid(column = 1, row=1, rowspan=2) 
ctr_right = Frame(center, bg='green', width=100, height=190, padx=3, pady=3).grid(column = 2, row=1, rowspan=2) 

btm_frame = Frame(root, bg='white', width = 450, height = 45, pady=3).grid(row = 3, columnspan = 3) 
btm_frame2 = Frame(root, bg='lavender', width = 450, height = 60, pady=3).grid(row = 4, columnspan = 3) 


root.mainloop() 

Cụ thể, nhãn và vật dụng nhập của tôi ở đâu và làm cách nào để trông giống như mục tiêu (khung trên cùng, phần còn lại dành cho sau này).

+0

nếu có thể giúp một chút nếu hai hình ảnh sử dụng màu sắc tương tự, trừ khi họ đang có và bạn đang nói rằng cửa sổ màu xanh thực sự nên ở phía dưới thậm chí mặc dù mã đặt nó ở bên trái. –

Trả lời

14

Tôi cho rằng khung chứa 'không gian lưới' của mình

Đó là một giả định chính xác.

Bạn chỉ có thể thấy một trong các trường nhập ở bên phải khung màu xanh lá cây . Tại sao nó lại đến đó?

Vấn đề bắt đầu ở đây:

top_frame = Frame(root, ...).grid(row=0, ...) 

Trong python, x = y().z() sẽ luôn đặt x đến kết quả của .z(). Trong trường hợp top_frame = Frame(...).grid(...), grid(...) luôn trả về None vì vậy top_frame sẽ là None. Điều đó gây ra mọi widget mà bạn nghĩ là đi vào khung trên cùng để thực sự đi vào cửa sổ gốc.

Giải pháp Tổng quan

Như một quy luật chung của ngón tay cái, bạn nên bao giờ gọi grid, pack hoặc place như một phần của báo cáo kết quả tương tự mà tạo ra các widget. Một phần nó là cho hành vi chính xác này mà bạn đang gặp phải, nhưng cũng bởi vì tôi nghĩ rằng nó làm cho mã của bạn khó viết hơn và khó hơn để duy trì theo thời gian.

Tạo widget và bố cục tiện ích con là hai thứ khác nhau.Theo kinh nghiệm của tôi, các sự cố bố cục là đáng kể dễ debug hơn khi bạn nhóm các lệnh bố cục lại với nhau.

Ngoài ra, bạn phải nhất quán khi sử dụng lưới và luôn đặt các tùy chọn theo cùng một thứ tự để bạn có thể dễ dàng hình dung bố cục hơn. Và cuối cùng, khi sử dụng grid, bạn nên có thói quen luôn chỉ định tùy chọn sticky và luôn cung cấp một hàng và một cột trong mỗi khung chứa một trọng số khác 0.

Ví dụ giải pháp

Đây là cách tôi sẽ viết mã của bạn. Nó dài hơn nhiều, nhưng dễ hiểu hơn nhiều.

from Tkinter import * 

root = Tk() 
root.title('Model Definition') 
root.geometry('{}x{}'.format(460, 350)) 

# create all of the main containers 
top_frame = Frame(root, bg='cyan', width=450, height=50, pady=3) 
center = Frame(root, bg='gray2', width=50, height=40, padx=3, pady=3) 
btm_frame = Frame(root, bg='white', width=450, height=45, pady=3) 
btm_frame2 = Frame(root, bg='lavender', width=450, height=60, pady=3) 

# layout all of the main containers 
root.grid_rowconfigure(1, weight=1) 
root.grid_columnconfigure(0, weight=1) 

top_frame.grid(row=0, sticky="ew") 
center.grid(row=1, sticky="nsew") 
btm_frame.grid(row=3, sticky="ew") 
btm_frame2.grid(row=4, sticky="ew") 

# create the widgets for the top frame 
model_label = Label(top_frame, text='Model Dimensions') 
width_label = Label(top_frame, text='Width:') 
length_label = Label(top_frame, text='Length:') 
entry_W = Entry(top_frame, background="pink") 
entry_L = Entry(top_frame, background="orange") 

# layout the widgets in the top frame 
model_label.grid(row=0, columnspan=3) 
width_label.grid(row=1, column=0) 
length_label.grid(row=1, column=2) 
entry_W.grid(row=1, column=1) 
entry_L.grid(row=1, column=3) 

# create the center widgets 
center.grid_rowconfigure(0, weight=1) 
center.grid_columnconfigure(1, weight=1) 

ctr_left = Frame(center, bg='blue', width=100, height=190) 
ctr_mid = Frame(center, bg='yellow', width=250, height=190, padx=3, pady=3) 
ctr_right = Frame(center, bg='green', width=100, height=190, padx=3, pady=3) 

ctr_left.grid(row=0, column=0, sticky="ns") 
ctr_mid.grid(row=0, column=1, sticky="nsew") 
ctr_right.grid(row=0, column=2, sticky="ns") 

root.mainloop() 

Kết quả:

screenshot of running example

+0

wahoo - rất nhiều, cảm ơn rất nhiều. Tôi sẽ xem xét cẩn thận. Tôi đồng ý với nhận xét về màu sắc, tôi không chú ý đủ gần. – shawn

2

variable = Widget(...).grid() gán None để biến vì grid()/pack()/place() trở None

sử dụng

variable = Widget(...) 
variable.grid() # .pack() .place() 
Các vấn đề liên quan