使用.pack的状态栏不会超出我的.grid框架

时间:2019-06-30 22:48:15

标签: python-3.x tkinter

我终于沉迷于编程,最近才开始将头放在类/子类/继承等方面。

问题 我的root.geometry设置为500x500,但我的状态栏没有超出GUI顶部标签所具有的网格框架。结果是在整个窗口底部的下面是一个微型状态栏。

from tkinter import * #Yes -- I know this crowds the namespace -- I'll change it later

UPDATE_RATE = 1000

class Application(Frame):
    global beginupdate
    beginupdate = False

    def __init__(self, master):

        """ Initialize the frame """
        Frame.__init__(self, master)
        self.grid(sticky=NSEW)
        self.create_widgets()
        self.updater()

    def create_widgets(self):

        # ********** Status Bar **********
        self.status_frame = Frame(self)
        self.healthstatus = StringVar()
        self.status = Label(self.status_frame, textvariable=self.healthstatus, bd=1, relief=SUNKEN, anchor=W)
        self.status_frame.pack(side=BOTTOM, fill='both', expand=TRUE)
        self.status.pack(side=BOTTOM, fill='both', expand=TRUE)

    def update_something1(self):
        if beginupdate:
            donothing()
        print('Updated')

    def updater(self):
        global beginupdate

        self.update_something1()
        beginupdate = True
        self.after(UPDATE_RATE, self.updater)


def donothing():
    print("ok ok I won't")


root = Tk()
root.configure(background='black')
root.geometry("500x500")

app = Application(root)
root.mainloop()

我花了将近4个小时来尝试解决这个愚蠢的状态栏。有人有什么建议吗?

1 个答案:

答案 0 :(得分:0)

问题的根源是您创建的小部件中没有任何东西,因此它们的自然大小将只有几像素高和宽。即使您将窗口强制为500x500,也看不到任何东西,因为它们都非常小。

主要原因是您使用的是grid,默认情况下grid仅使用显示其内容所需的最小空间。因此,带有小标签的小框架仅出现在根窗口左上角(行0,列0)的几个像素中。

我个人的经验法则是,如果您仅将一个小部件放在另一个小部件内,则始终使用pack,例如将app放在根窗口中的情况。您可以使用grid来解决此问题,方法是为行零和列零赋予权重,但是当pack仅需要权重时,总共需要三行。

因此,第一步是从__init__删除以下代码行:

    self.grid(sticky=NSEW)

我认为一个小部件(在您的情况下,Application)将自己放置在另一个小部件中是一种不好的做法。相反,创建Application的代码应负责将其添加到根窗口。

为此,请在创建app之后立即且在调用mainloop之前添加以下行:

app.pack(side="top", fill="both", expand=True)

这时您将看不到任何东西,因为没有什么可看的。嗯,这并不完全正确-根窗口是黑色的,但您看到的只是白色(或灰色),因为这是状态标签的颜色及其所在的框架。此外,您还要求状态标签完全填满其框架,并且您已要求框架填满窗口。

您可以通过在标签中添加字符串来查看。例如,在创建self.healthstatus之后添加此代码:

self.healthstatus.set("Hello, World!")

您应该在屏幕的垂直中间看到消息,并向左对齐。

正如我先前所写,您已请求状态标签和框架填充其窗口。我怀疑您是否真的想要那个。将这两个小部件上的pack调用方式更改为:

self.status_frame.pack(side=BOTTOM, fill='x', expand=False)
self.status.pack(side=BOTTOM, fill='x', expand=False)

请注意,这将阻止这些小部件扩展以填充所有空间,而是仅在x方向上填充而保留在窗口底部。

这是一个有效的版本,尽管我删除了不必要的updater函数,因为它与布局问题无关:

from tkinter import *

class Application(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)
        self.create_widgets()

    def create_widgets(self):
        self.status_frame = Frame(self)
        self.healthstatus = StringVar()
        self.healthstatus.set("Hello, World!")
        self.status = Label(self.status_frame, textvariable=self.healthstatus, bd=1, relief=SUNKEN, anchor=W)

        self.status_frame.pack(side=BOTTOM, fill='x', expand=False)
        self.status.pack(side=BOTTOM, fill='x', expand=False)

root = Tk()
root.configure(background='black')
root.geometry("500x500")

app = Application(root)
app.pack(fill="both", expand=True)

root.mainloop()

window screenshot