Я делаю свой первый графический интерфейс и не понимаю, как работают фреймы. Как разместить этикетку внутри рамки?
class GUI:
def __init__(self, window):
self.window = window
self.window.title("RPG")
self.window.geometry("600x400")
self.window.configure(bg="black")
self.window.grid_anchor(anchor=CENTER)
self.header = Frame(self.window, bg="green", height=25, width=600)
self.frame = Frame(self.window, bg="red", height=375, width=600)
self.header.grid(row=0)
self.frame.grid(row=1)
self.label1 = Label(self.header, text="Hello World", bg="black", fg="white")
self.label2 = Label(self.frame, text="This is the Game")
self.label1.grid(row=0, column=0)
self.label2.grid(row=0, column=0)
root = Tk()
gui = GUI(root)
root.mainloop()
Я хотел бы отобразить оба кадра, так же, как и цветовые блоки, и иметь центрированную метку в каждом, но она вообще не отображает рамки, только метки.
2 ответа
По умолчанию рамки (и все остальные виджеты) будут уменьшаться или расширяться, чтобы соответствовать их содержимому. Таким образом, когда вы помещаете метки в рамки, рамки сжимаются, чтобы соответствовать метке.
Кроме того, вы используете grid
, а grid
создаст наименьшие возможные строки и столбцы, чтобы соответствовать тому, что находится в строке и столбце. grid
использует только столько места, сколько необходимо, и не будет использовать дополнительное пространство, если вы не настроили его для этого. Кроме того, сетка будет центрировать элементы в выделенном пространстве, поэтому даже если столбец или строка больше, чем элемент, элемент не заполнит эту строку или столбец.
Поначалу это может показаться нелогичным, но на самом деле эти правила работают довольно хорошо, когда вы понимаете, как grid
работает.
Предполагая, что вы хотите, чтобы header
и frame
заполнили окно, вам необходимо настроить grid
, чтобы знать, что делать с дополнительным доступным пространством. Это делается путем присвоения строке или столбцу «веса».
Например, предполагая, что вы хотите, чтобы self.header
был горизонтальным условием в верхней части, а self.frame
занимал все дополнительное пространство, необходимо добавить следующий оператор:
self.grid_rowconfigure(1, weight=1)
self.grid_columnconfigure(0, weight=1)
С нулевой строкой, имеющей вес по умолчанию 0 (ноль), grid
предоставит все дополнительное вертикальное пространство self.frame
. Установив вес 1 (один) в нулевой столбец, этот столбец получит все дополнительное горизонтальное пространство.
При этом для фрейма будет выделено достаточно места сверху для заголовка, а все дополнительное пространство будет выделено для self.frame
. Есть еще один шаг, который нужно сделать.
Несмотря на то, что self.frame
предоставлено все дополнительное пространство, вы должны указать grid
растянуть рамку, чтобы она занимала все выделенное пространство. Вы делаете это с помощью опции sticky
. Он принимает буквы, представляющие точки на компасе: n (север), s (юг), e (восток) и w (запад). Чтобы кадр занимал все выделенное пространство, нужно, чтобы он «прилипал» ко всем четырем сторонам:
self.frame.grid(row=1, column=0, sticky="nsew")
Точно так же, чтобы растянуть заголовок и заполнить его по горизонтали, можно сказать, что он «прилипает» к востоку и западу:
self.header.grid(row=0, column=0, sticky="ew")
При этом зеленая рамка заголовка заполнит верхнюю часть экрана, а красная рамка заполнит все остальное пространство.
Это, вероятно, все еще не совсем то, что вы хотите, но проблема идентична. Если вы хотите, чтобы метка была распределена по всему пространству в заголовке, вы должны использовать для веса строки и столбца 0. Делая это, вы центрируете метку. Если вы хотите, чтобы метка занимала разрешенное пространство, используйте sticky
.
Аналогично, если вы хотите, чтобы все остальные метки заполняли нижнюю рамку, присвойте этой строке и столбцу вес, и метка будет центрирована в пространстве. Если вы хотите, чтобы он занимал все выделенное пространство, используйте sticky
.
Например:
self.header.grid_rowconfigure(0, weight=1)
self.header.grid_columnconfigure(0, weight=1)
self.frame.grid_rowconfigure(0, weight=1)
self.frame.grid_columnconfigure(0, weight=1)
Граница по умолчанию для Frame
равна 0
, что означает отсутствие границы. Если вы хотите один, то укажите значение больше нуля. Например, обратите внимание на добавленные аргументы ключевого слова bd=1
(вы также можете использовать borderwidth=1
):
Кроме того, если вы хотите, чтобы текст центрировался в надписях, вы должны дать им минимум width
(количество символов) и указать, как вы хотите, чтобы текст выравнивался в этом пространстве с помощью anchor
вариант.
import tkinter as tk
class GUI:
def __init__(self, window):
self.window = window
self.window.title("RPG")
self.window.geometry("600x400")
self.window.configure(bg="black")
self.window.grid_anchor(anchor="center")
self.header = tk.Frame(self.window, bg="green", height=25, width=600, bd=1)
self.frame = tk.Frame(self.window, bg="red", height=375, width=600, bd=1)
self.header.grid(row=0)
self.frame.grid(row=1)
self.label1 = tk.Label(self.header, text="Hello World", bg="black", fg="white",
width=15, anchor='center') # ADDED
self.label2 = tk.Label(self.frame, text="This is the Game",
width=15, anchor='center') # ADDED
self.label1.grid(row=0, column=0)
self.label2.grid(row=0, column=0)
root = tk.Tk()
gui = GUI(root)
root.mainloop()
Похожие вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.