首页 > 解决方案 > 使用 .pack 的状态栏没有超出我的 .grid 框架

问题描述

我终于开始涉足编程,最近才开始关注类/子类/继承等。

问题 我的 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 个小时试图解决这个愚蠢的状态栏。有人有建议吗?

标签: python-3.xtkinter

解决方案


问题的根源在于您创建的小部件中没有任何内容,因此它们的自然大小将只有几个像素的高和宽。即使您将窗口强制设置为 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()

窗口截图


推荐阅读