Почему внутренняя прокладка применяется только справа? - PullRequest
1 голос
/ 23 октября 2019

Текущие ответы обеспечивают обходной путь с помощью аргумента ключевого слова padding. По-прежнему необходимо объяснение ПОЧЕМУ сбой ipadx.


MCVE

import Tkinter as tk
import ttk

root = tk.Tk()
root.minsize(200, 100)
inner_frame = ttk.LabelFrame(root, text='inner_frame')
inner_frame.grid(row=0, column=0)

button = ttk.Button(inner_frame, text='this is a button')
button.grid(row=0, column=0)

# this does not work as expected
inner_frame.grid_configure(ipadx=20)

root.mainloop()

Вывод

Вопрос

Почему внутренняя прокладка для inner_frame применяется только справа? Как мне применить его с обеих сторон?

Ответы [ 3 ]

2 голосов
/ 24 октября 2019

Интересно, и я не знаю, является ли это ошибкой, ваша проблема решается путем расширения столбца, содержащего кнопку, до минимального горизонтального размера.

Минимальный горизонтальный размер столбца 0 ввнутренний фрейм - это горизонтальный размер содержимого, которым является кнопка.

Если вы добавите inner_frame.columnconfigure(0, weight=1), то внутреннее заполнение будет работать так, как ожидается:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()

inner_frame = ttk.LabelFrame(root_frame, text="inner_frame")
inner_frame.grid(row=0, column=0)

inner_frame.columnconfigure(0, weight=1)

button = ttk.Button(inner_frame, text="this is a button")
button.grid(row=0, column=0)

# this works expected:
inner_frame.grid_configure(ipadx=20)

root.mainloop()

Обратите внимание, что grid_configure изменяет столбец 0 по умолчанию, поэтому здесь мы добавляем внутренний отступ к ячейкам в столбце 0.

Я не знаю точно, почему это происходит. Он не упоминается в документах по сетке Tcl (http://tcl.tk/man/tcl8.5/TkCmd/grid.htm#M13).

Интересно, что в этой ссылке упоминается какой-то особый случай, касающийся размера кадра с использованием внутреннего отступа (внизу страницы, в разделе «Внутреннее заполнение»): https://tkdocs.com/tutorial/grid.html

Разница может быть незначительной. Допустим, у вас есть кадр размером 20x20, и укажите нормальное (внешнее) заполнение по 5 пикселей с каждой стороны. Кадр запросит прямоугольник 20x20 (его естественный размер) от менеджера геометрии. Обычно это то, что ему будет предоставлено, поэтому он получит прямоугольник 20x20 для рамки, окруженный 5-пиксельной границей.

С внутренним заполнением геометрияМенеджер эффективно добавит дополнительный отступ к виджету, когда вычислит его естественный размер, как если бы виджет запросил прямоугольник 30x30. Если рамка центрирована или прикреплена к одной стороне или углу (используя «липкий»), вы 'В итоге получится кадр 20x20 с дополнительным пространством вокруг него. Если, однако, кадр настроен на растяжение (т. е. «липкое» значение «мы», «нс»)", или" nwes "), он заполнит дополнительное пространство, в результате чего будет кадр 30x30, без рамки.

Но это написано запутанно, и я не могу полностью понять, что они означают (или даже если они правильны в современном Python). Если кто-то знает, что означает этот абзац выше, обязательно прокомментируйте ниже и дайте нам знать!

Добавление внутреннего отступа к кадру в целом

Вы можете добавить внутреннее заполнение, используя стили или передаваянепосредственно в качестве аргумента для конструктора фрейма:

ttk.LabelFrame(root, text="inner", padding=(20, 0))

Там значение заполнения может принимать либо:

  • Одно значение для заполнения со всех сторон
  • Два значения для x и y (в этом порядке)
  • Четыре значения для заполнения, начинающегося слева и идущего по часовой стрелке.
1 голос
/ 26 октября 2019

В вашем случае, ipadx не сбой. Он работает как задумано, просто то, как он работает, не очень интуитивно понятно, особенно когда вы применяете его к кадру.

Чтобы лучше визуализировать происходящее, давайте применим значение ipadx к кнопке, а не к рамке. Таким образом, мы можем видеть отступ относительно метки на кнопке.

Например, добавьте две кнопки вместо одной. Дайте одному ipadx из 20, а другому ipadx = 0.

button1 = ttk.Button(inner_frame, text='this is a button')
button2 = ttk.Button(inner_frame, text='this is a button')

button1.grid(row=0, column=0, ipadx=20)
button2.grid(row=1, column=0, ipadx=0)

Обратите внимание, что кнопка с ipadx=20 шире, и дополнительное пространство находится внутри кнопки, а некак поле вокруг кнопки.

screenshot of two buttons

То же самое происходит с inner_frame: когда он добавляется к своему родителю, дополнительное пространстводобавляется внутри рамки, эффективно увеличивая inner_frame. Вы не можете видеть его, потому что он добавлен в пустое пространство уже внутри фрейма.

Вот важная часть: если вы добавляете виджет в inner_frame, grid ничего не знает о значениях ipadx, применяемых к inner_frame - эта опция ipadx применяется только кinner_frame и его родитель , а не его дети. В момент добавления виджетов внутри inner_frame, grid знает только, что inner_frame имеет ширину X пикселей.

Чтобы проиллюстрировать это, мы можем добавить ярлык к кнопке, аналогично тому, как ваш исходный код добавляет кнопку в рамку. (примечание: мы отключим распространение геометрии, чтобы кнопка не уменьшалась).

button1.grid_propagate(False)
label = ttk.Label(button1, text="x")
label.grid(row=0, column=0)

Вы должны увидеть окно, которое выглядит примерно так:

screenshot of label inside button

Видите, как "х" находится на крайнем левом краю кнопки? Это потому, что он ничего не знает о значении ipadx, примененном к его родителю. Все, что он знает, это то, что кнопка является виджетом X пикселей, и она должна быть на левом краю кнопки.

Это то, что происходит с вашей оригинальной рамкой и кнопкой - кнопка добавляется внутрирама, используя все пространство внутри рамы.

0 голосов
/ 24 октября 2019

До сих пор я выяснил, что использование padding=... в конструкторе LabelFrame дает правильный результат.

Если вы удалите строку

inner_frame.grid_configure(ipadx=20)

и используете

inner_frame = ttk.LabelFrame(root, text='inner_frame', padding=[20, 0])

или альтернативно

inner_frame['padding'] = [20, 0]

результат выглядит следующим образом:

Понятия не имею, зачем использовать ipadx - grid_configure не работает должным образом.

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