Tkinter pack()几何管理器混乱

时间:2015-04-06 15:46:07

标签: python tkinter

就在我认为我理解pack()经理时,我遇到了以下问题:

我创建了两个框架(每个框架都有一个Button),并希望将它们水平打包到另一个框架(这是主框架)中。出于某种原因,它们垂直出现。如果我用一个简单的按钮替换第一帧,则使用相同的pack()指令水平打包按钮+第二帧

这是该计划的一个提炼(但有效)版本:

from Tkinter import *

class QuitBtn1(Button):
    def __init__(self):
        Button.__init__(self)
        self["text"] = "Quit"
        self["fg"] = "red"
        self["command"] = self.quit

class QuitBtn(Frame):
    def __init__(self):
        Frame.__init__(self)

        b = Button(text = "Quit", fg = "red", command = self.quit)
        b.pack()

class HiBtn(Frame):
    def __init__(self):
        Frame.__init__(self)

        b = Button(text = "Hi there", fg = "blue", command = self.quit)
        b.pack()

class App(Frame):
    def __init__(self, master = None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def say_hi(self):
        print "hi there, everyone!"

    def createWidgets(self):
        self.QUIT = QuitBtn().pack(side = LEFT)
        self.hi_there = HiBtn().pack(side = LEFT)


root = Tk()
app = App(master = root)
app.mainloop()
root.destroy()

运行时,它会生成两个垂直打包的帧。只需切换QuitBtn1QuitBtn的名称(将框架更改为简单按钮),即可将打包更改为水平。

我已经看了几十个例子,似乎以某种方式避免了这个确切的结构。我在这里做错了吗?

2 个答案:

答案 0 :(得分:3)

问题在于,您不能将任何小部件作为父级,因此它们都默认为根窗口。即使你认为按钮在框架内部,它们也不是。

因为pack的默认设置是放在顶部,当您在按钮上调用pack()时,它们将堆叠在根窗口中。你的两个框架,因为它们中没有任何东西,大小为1x1,所以你无法看到它们。 包装在左侧,您无法看到它们。

解决方案是正确嵌套您的小部件。例如:

class QuitBtn(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)

        b = Button(self, text = "Quit", fg = "red", command = self.quit)
        b.pack()

def createWidgets(self):
    self.QUIT = QuitBtn(self)
    ...
    self.QUIT.pack(side = LEFT)
    ...

上面在QuitBtn框架内创建了一个按钮小部件,并将其打包到该框架的顶部。之后,该帧(及其内容)将被打包到主帧的左侧。

将窗口小部件的创建与窗口小部件的布局分开也很重要。当您执行self.QUIT = QuitBtn(...).pack(...)之类的操作时,self.QUIT将设置为None,因为这是pack(...)返回的内容。另外,根据我的经验,将给定包含框架的所有布局移动到单独的块中可以更轻松地管理布局。

答案 1 :(得分:1)

一种方法是使用in_=参数告诉pack您要将每个窗口小部件打包的内容。所以:

from Tkinter import *

class QuitBtn(Frame):
    def __init__(self):
        Frame.__init__(self)

        b = Button(text = "Quit", fg = "red", command = self.quit)
        b.pack(in_=self)                                                   # Here

class HiBtn(Frame):
    def __init__(self):
        Frame.__init__(self)

        b = Button(text = "Hi there", fg = "blue", command = self.quit)
        b.pack(in_=self)                                                   # Here

class App(Frame):
    def __init__(self, master = None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def say_hi(self):
        print "hi there, everyone!"

    def createWidgets(self):
        self.QUIT = QuitBtn().pack(side = LEFT)       
        self.hi_there = HiBtn().pack(side = LEFT)      


root = Tk()
app = App(master = root)
app.mainloop()
root.destroy()

在帧内生成按钮的水平排列(每个按钮位于App框架内)。

enter image description here

我认为我自己并不需要这些,但我不记得曾经使用顶级课程声明小部件。

作为旁注,非常感谢您提供代码的精炼版,以证明同样的问题!我希望这更常见。