Строка состояния с использованием .pack не выходит за рамки моего .grid - PullRequest
0 голосов
/ 01 июля 2019

Я наконец-то увлекся программированием и совсем недавно начал думать о классах / подклассах / наследовании и т. Д.

Проблема Мой root.geometry установлен на 500x500, но мой статусполоса не выходит за рамки сетки, которую я имею для надписей в верхней части графического интерфейса.В результате получается небольшая мини-строка состояния, расположенная внизу всего окна.

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 голосов
/ 02 июля 2019

Корень проблемы в том, что вы создали виджеты, в которых ничего нет, поэтому их естественный размер будет всего несколько пикселей в высоту и ширину. Даже если вы устанавливаете окно 500х500, ничего не видно, потому что все они очень маленькие.

Основная причина этого заключается в том, что вы используете 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...