Я использую tkinter для написания карточной игры, и у меня проблемы с «липкой» конфигурацией диспетчера компоновки сетки. Я хотел бы помочь исправить мой код, чтобы фреймы отображались в желаемом месте. В моем коде и иллюстрации ниже есть кадр (b2), который содержит два других (один зеленый, b2a; и один красный; b2b) кадра. Я хотел бы отобразить фрейм b2 внизу родительского фрейма (фрейм b). Я пробовал различные комбинации N + S + E + W в качестве аргументов для «липкости» как для кадра b2, так и для дочерних кадров b2a и b2b. Однако мне не удалось заставить кадр b2 (и, что более важно, b2a и b2b) отображаться в желаемом месте (нижнее изображение ниже с правильным размещением было сделано в Illustrator).
В частности, кажется, что липкие аргументы в строках 27, 36 и 37 не влияют на размещение кадра b2, b2a и b2b внутри кадра b.
from tkinter import *
from PIL import Image, ImageTk
def main(root):
cons = Frame(root)
cons.grid()
frameDict = setup_frames(cons)
populate_frames(frameDict)
def setup_frames(cons):
frame = {}
# Parental Frames
frame['a'] = Frame(cons, borderwidth=2, relief='groove')
frame['b'] = Frame(cons, borderwidth=2, relief='groove')
frame['c'] = Frame(cons, borderwidth=2, relief='groove')
frame['a'].grid(row=0, column=0, sticky=N+S+E+W)
frame['b'].grid(row=0, column=1, sticky=N+S+E+W)
frame['c'].grid(row=1, column=0, columnspan=2)
# Progeny 0 Frames:
frame['b1'] = Frame(frame['b'], borderwidth=2, relief='groove')
frame['b2'] = Frame(frame['b'], borderwidth=2, relief='groove')
frame['b1'].grid(row=0, column=0, sticky=N+S+E+W)
frame['b2'].grid(row=1, column=0, sticky=N+S+E+W)
# Progeny 1 Frames:
frame['b2a'] = Frame(frame['b2'], borderwidth=2, relief='groove',
background='green')
frame['b2b'] = Frame(frame['b2'], borderwidth=2, relief='groove',
background='red')
frame['b2a'].grid(row=0, column=0, sticky=S)
frame['b2b'].grid(row=0, column=1, sticky=SW)
return frame
def populate_frames(fr):
# Populating 'a' frame
aLab = Label(fr['a'], image=img[0])
aLab.grid()
# Populating b2a & b2b frames
bLab = Label(fr['b2a'], image=img[1])
bLab.grid(row=0, column=0)
bLab = Label(fr['b2b'], image=img[2])
bLab.grid(row=0, column=1)
# Populating c1 frame
cLab = Label(fr['c'], image=img[3])
cLab.grid()
if __name__ == '__main__':
root = Tk()
img = []
w = [40, 160, 80, 480]
h = [180, 60, 60, 60]
for i in range(4):
a = Image.new('RGBA', (w[i], h[i]))
b = ImageTk.PhotoImage(a)
img.append(b)
main(root)
На изображениях ниже показано, где отображаются неправильные кадры (зеленый и красный) (вверху) и где я бы хотел, чтобы они отображались (внизу).
Может ли кто-нибудь помочь мне отобразить кадр b2 (и, в конечном итоге, b2a и b2b) в правильном положении (редактировать: внизу кадра b и от правой стороны кадра a до правой стороны кадра c)?
Обновление: я решил обе проблемы (вертикальное размещение и горизонтальное выравнивание кадра b2), используя веса сетки, как предложил Брайан. Решение проблемы вертикального размещения простое, но я бы не предсказал решение проблемы горизонтального выравнивания.
Я решил проблему вертикального размещения, присвоив вес = 1 строке 0 в кадре b (в результате получилась верхняя панель рисунка ниже).
Я решил проблему горизонтального выравнивания (где кадры b1 и b2 не растягивались, чтобы заполнить кадр b), присвоив вес = 1 столбцу 0 в кадре b. Контуры рамки на рисунке ниже показывают, что рамка b уже растянута от правой стороны рамки a до правой стороны рамки c. Мне странно, что для того, чтобы дочерние фреймы могли заполняться по горизонтали, потребовалось бы присвоить вес единственному столбцу во фрейме. В любом случае, я вставил свой рабочий код ниже. Строки 40 и 41 решили мою проблему.
from tkinter import *
from PIL import Image, ImageTk
def main(root):
cons = Frame(root)
cons.grid()
frameDict = setup_frames(cons)
populate_frames(frameDict)
def setup_frames(cons):
frame = {}
# Parental Frames
frame['a'] = Frame(cons, borderwidth=2, relief='groove')
frame['b'] = Frame(cons, borderwidth=2, relief='groove')
frame['c'] = Frame(cons, borderwidth=2, relief='groove')
frame['a'].grid(row=0, column=0, sticky=N+S+E+W)
frame['b'].grid(row=0, column=1, sticky=N+S+E+W)
frame['c'].grid(row=1, column=0, columnspan=2)
# Progeny 0 Frames:
frame['b1'] = Frame(frame['b'], borderwidth=2, relief='groove')
frame['b2'] = Frame(frame['b'], borderwidth=2, relief='groove')
frame['b1'].grid(row=0, column=0, sticky=N+S+E+W)
frame['b2'].grid(row=1, column=0, sticky=N+S+E+W)
# Progeny 1 Frames:
frame['b2a'] = Frame(frame['b2'], borderwidth=2, relief='groove',
background='green')
frame['b2b'] = Frame(frame['b2'], borderwidth=2, relief='groove',
background='red')
frame['b2a'].grid(row=0, column=0, sticky=S)
frame['b2b'].grid(row=0, column=1, sticky=SW)
# Weighting
frame['b'].grid_rowconfigure(0, weight=1)
frame['b'].grid_columnconfigure(0, weight=1)
return frame
def populate_frames(fr):
# Populating 'a' frame
aLab = Label(fr['a'], image=img[0])
aLab.grid()
# Populating b2a & b2b frames
bLab = Label(fr['b2a'], image=img[1])
bLab.grid(row=0, column=0)
bLab = Label(fr['b2b'], image=img[2])
bLab.grid(row=0, column=1)
# Populating c1 frame
cLab = Label(fr['c'], image=img[3])
cLab.grid()
if __name__ == '__main__':
root = Tk()
img = []
w = [40, 160, 80, 480]
h = [180, 60, 60, 60]
for i in range(4):
a = Image.new('RGBA', (w[i], h[i]))
b = ImageTk.PhotoImage(a)
img.append(b)
main(root)
В соответствии с советом Брайана, на самом деле кажется хорошим практическим правилом назначать вес по крайней мере одному столбцу и одной строке в каждом контейнере.
Вот до и после того, как я исправил проблему горизонтального выравнивания:
Использование Python 3.4, Йосемити