tkinter sticky不适用于某些帧

2024-10-02 00:22:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我在用tkinter写一个纸牌游戏,我对网格布局管理器的“粘性”配置有问题。我想帮助修复我的代码,使框架显示在所需的位置。在下面的代码和插图中,有一个框架(b2)包含另外两个(一个绿色的b2 a;一个红色的b2b)框架。我想在父帧(帧b)的底部显示帧b2。我已经尝试了N+S+E+W的各种组合作为“粘性”的参数,对于帧b2和子帧b2a和b2b,但是,我无法使帧b2(更重要的是b2a和b2b)出现在所需的位置(下图中的正确位置是在Illustrator中生成的)。

尤其是,第27、36和37行中的粘性参数似乎对框架b2、b2a和b2 b在框架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帧(最终是b2 a和b2 b)显示在正确的位置吗(编辑:在b帧的底部,从a帧的右侧到c帧的右侧)?

illustration of incorrect and correct frame placement

更新: 正如Bryan建议的那样,我已经使用网格权重解决了这两个问题(框架b2的垂直放置和水平对齐)。垂直放置问题的解决方案很简单,但我不会预测水平对齐问题的解决方案。

我解决了垂直放置的问题,在框架b中给第0行赋予了权重=1(结果是下图的上面板)。

我解决了水平对齐问题(其中帧b1和b2没有拉伸到填充帧b),方法是将weight=1分配给帧b中的列0。下图中的帧轮廓显示,帧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)

按照布赖恩的建议,给每个容器中的至少一列和一行指定一个权重似乎是一个很好的经验法则。

下面是我修复水平对齐问题前后的情况:

before and after horizontal justification

使用Python 3.4,Yosemite


Tags: imgframescolumnframeb2gridrowsticky

热门问题