2015-12-14 2 views
9

Мои gui layoutTkinter GUI макет с использованием кадров и сетки

gui layout

выглядит почти ничего подобного what I expect

what I expect

поэтому я предполагаю, что есть некоторые основы, которые я не понимаю.

Я предположил, что кадры содержат свое «пространство сетки» (строка, столбец), но поведение, которое я вижу, не выдерживает этого, и я в недоумении за то, что все работает так, как я хочу для вершины Рамка. Мои метки должны находиться в одной строке L до R под меткой фрейма, которая охватывает весь кадр, за исключением того, что это не так. Я хочу, чтобы фактический взгляд больше напоминал цель jpg, и я хочу использовать сетку для этого.

Вы можете просто увидеть одно из полей ввода справа от зеленой рамки. Почему это происходит?

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() 

Так точно, где же мои ярлыки и виджеты Вступительные идут, и как я могу заставить их выглядеть как цель (верхний фрейм, остальные для позже).

+0

если бы помочь немного, если два изображения использует ту же цветовую схему, если они не являются, и вы говорите, что синее окно действительно должно быть на дне даже хотя код помещает его влево. –

ответ

14

Я предположил, что кадры содержат свои собственные 'сетки пространство'

То есть правильное предположение.

Вы можете просто увидеть одно из полей ввода справа от зеленого кадра . Почему это происходит?

Проблема начинается здесь:

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

В питона, x = y().z() всегда будет установить x в результате .z(). В случае top_frame = Frame(...).grid(...), grid(...) всегда возвращает None, поэтому top_frame будет None. Это приводит к тому, что каждый виджет, который, по вашему мнению, входит в верхний фрейм, действительно находится в корневом окне.

Обзор решения

Как общее правило, вы должны никогда вызов grid, pack или place как часть того же оператора, что создает виджет. Частично это для того точного поведения, которое вы испытываете, но также потому, что я думаю, что это делает ваш код сложнее писать и с течением времени сдерживать.

Создание виджетов и расположение виджетов - это две разные вещи.По моему опыту, проблемы с компоновкой значительно легче отлаживать при группировке команд компоновки.

Кроме того, вы должны быть последовательны при использовании сетки и всегда ставить опции в одном порядке, чтобы вы могли легче визуализировать макет. И, наконец, при использовании grid вы должны привыкнуть всегда указывать опцию sticky и всегда указывать одну строку и один столбец в каждом из которых содержит ненулевой вес.

Пример решения

Вот как я бы написать свой код. Это намного дольше, но гораздо легче понять.

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() 

Результат:

screenshot of running example

+0

wahoo - много, много спасибо. Я рассмотрю внимательно. Я согласен с комментарием цветовой схемы, я не обращал достаточно пристального внимания. – shawn

2

variable = Widget(...).grid() присваивает None к переменной, потому что grid()/pack()/place() возвращение None

использование

variable = Widget(...) 
variable.grid() # .pack() .place() 
Смежные вопросы