Как сделать графический интерфейс в Tkinter масштабируемым

Я пытаюсь создать графический интерфейс для проекта. Код для которого ниже. У меня вопрос по масштабируемости. В моем сценарии я заставляю Tkinter отображать графический интерфейс в полноэкранном режиме. Однако из-за природы relx и полагаться на место он получает метку или кнопку, чтобы начать с относительных позиций x и y. Однако это будет означать, что на другом экране это не будет выглядеть так же. Например, поскольку relx и relay определяют, где начинается виджет (а не в середине), каждый раз, когда изменяется размер экрана, внешний вид меняется. Я показал два изображения, которые, как мне кажется, отображают мою точку зрения. На левом изображении мне удалось расположить виджет так, чтобы он находился посередине, однако из-за того, где начинается виджет при сжатии, закрытый виджет больше не находится посередине. Обратите внимание, что он по-прежнему начинается с того же relx и полагаться, но уже не посередине.

По сути, есть способ сделать его масштабируемым, чтобы он выглядел одинаково независимо от размера окна. Можно ли это сделать, убедившись, что relx и relay диктуют положение середины, а не начало виджета?

from tkinter import *
import tkinter.font as tkFont

root = Tk()
root.title("N Body Simulation")

def exitclick():
    root.destroy()

class FullScreenApp(object):
def __init__(self, master, **kwargs):
    self.master = master
    pad = 3
    self._geom = '200x200+0+0'
    master.geometry("{0}x{1}+0+0".format(
        master.winfo_screenwidth() - pad, master.winfo_screenheight() - pad))
    master.bind('<Escape>', self.toggle_geom)

def toggle_geom(self, event):
    geom = self.master.winfo_geometry()
    print(geom, self._geom)
    self.master.geometry(self._geom)
    self._geom = geom


frame = Frame(root)
frame.pack()

fontStyle = tkFont.Font(family = "Lucida Grande", size=20)
text_intro = "This is the GUI for the N-Body simulation, from here you can change the plents and the initial conditions"
label = Label(root, text=text_intro, font=fontStyle)
label.place(relx=0.1, rely=0.1)

close_button = Button(root, text = "Close", command=exitclick, height=10, width = 30)
# close_button.place(relx=0.8, rely=20)
close_button.place(relx=0.4, rely=0.8)


e = Entry(root, width=35, borderwidth=5)
app = FullScreenApp(root)

root.mainloop()

Как правило, grid и pack сделать адаптивный графический интерфейс намного проще, чем когда вы используете place. Что касается ваших комментариев о relx и rely, я не могу понять, о чем вы спрашиваете. Они относительны, поэтому relx 0,4 будет составлять 4/10 ширины окна, независимо от того, насколько большое или маленькое окно. Если вы хотите, чтобы метка находилась в определенном месте в пикселях, вы можете использовать абсолютные координаты. У нас нет возможности узнать, как вы хотите, чтобы пользовательский интерфейс выглядел, поэтому невозможно дать хороший совет, как его оформить.

Bryan Oakley 14.12.2020 23:05

«Можно ли это сделать, убедившись, что relx и relay определяют положение середины, а не начало виджета?» вы можете сделать это с опцией anchor к place. Трудно сказать, сработает ли это в вашей ситуации, поскольку неясно, чего вы пытаетесь достичь.

Bryan Oakley 14.12.2020 23:09

1. Я пытался использовать сетку, но при ее использовании, когда я увеличивал размер фигуры, она не масштабировалась соответствующим образом. 2. Что я имею в виду под относительными комментариями, так это то, что если вы уменьшите размер фигуры, это будет не просто уменьшенная версия большей фигуры. Соотношение расстояний будет различным в окнах разного размера. Этого бы не произошло, если бы relx диктовал, где находится середина виджета, а не начало.

Harry Spratt 15.12.2020 02:36

Извините за неясный вопрос, надеюсь, правки помогут. По сути, я спрашиваю, как сохранить виджет посередине, независимо от размера окна, что в настоящее время не так, как показано на двух рисунках.

Harry Spratt 15.12.2020 02:41
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
945
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать опцию anchor, чтобы контролировать, какая часть виджета находится в данной позиции.

Это каноническая документация для anchor из документации tcl/tk, слегка измененная для tkinter:

привязка где - где указывает, какая точка окна должна быть расположена в месте (x, y), выбранном параметрами x, y, relx и rely. Точка привязки относится к внешней области окна, включая его границу, если таковая имеется. Таким образом, если где есть se, то правый нижний угол границы окна появится в заданном (x, y) местоположении мастера. Положение привязки по умолчанию равно nw.

Допустимыми значениями для anchor являются строки nw, w, sw, s, se, e, ne, n и center.

Например, это позволит сохранить метку по центру независимо от размера окна, поместив центр виджета в относительные координаты .5/.5:

label = tk.Label(root, hello, world)
label.place(relx=.5, rely=5. anchor = "center")

Ах, хорошо, отлично, именно то, что я искал. Большое спасибо.

Harry Spratt 15.12.2020 03:21

Другие вопросы по теме