Кнопки разного размера в одинаково взвешенном сеточном менеджере? - PullRequest
1 голос
/ 15 октября 2019

Почему эти кнопки имеют разный размер при использовании одинаковых весов в сетке?

class Screen(tk.Tk):

    def __init__(self):
        super().__init__()

        f = tk.Frame(self)
        f.pack(fill=tk.BOTH, expand=True)
        f.grid_columnconfigure(0, weight=1)
        f.grid_columnconfigure(1, weight=1)
        f.grid_columnconfigure(2, weight=1)
        f.grid_columnconfigure(3, weight=1)

        l1 = tk.Label(f, text='Text')
        l1.grid(row=0, column=0, columnspan=4, sticky='nsew')

        l2 = tk.Label(f, text='Text', anchor='w')
        l2.grid(row=1, column=0, sticky='sw')

        self.e1 = tk.Entry(f)
        self.e1.grid(row=2, column=0, columnspan=3, sticky='nsew')

        self.b1 = tk.Button(f, text='B1')
        self.b1.grid(row=2, column=3, sticky='nsew')

        l3 = tk.Label(f, text='Text', anchor='w')
        l3.grid(row=3, column=0, sticky='sw')

        self.e2 = tk.Entry(f)
        self.e2.grid(row=4, column=0, ipady=2, columnspan=3, sticky='nsew')

        self.b2 = tk.Button(f, text='B2')
        self.b2.grid(row=5, column=2, sticky='nsew')
        self.b3 = tk.Button(f, text='B3')
        self.b3.grid(row=5, column=3, sticky='nsew', command=self.test)

        self.update_idletasks()
        self.geometry(f'500x{self.winfo_reqheight()}')
        self.resizable(False, False)

    def test(self):
        a = self.b1.winfo_width()
        b = self.b2.winfo_width()
        c = self.b3.winfo_width()
        print(a, b, c)

Вывод: 111 110 111

Кнопки B1 и B3 находятся в столбце 3 таблицы, а B2 - в столбце 2. Единственный способ убедиться, что они имеют одинаковый размер, - это установить для их конфигурации width что-то вроде width=10.

Желаемая раскладка:

+---------------------------------------------------------+
|                             L1                          |
+--------------+------------+--------------+--------------+
|      L2      |            |              |              |
+--------------+------------+--------------+--------------+
|                     E1                   |      B1      |
+--------------+------------+ -------------+--------------+
|      L3      |            |              |              |
+--------------+------------+--------------+--------------+
|                     E2                   |              |
+--------------+------------+ -------------+--------------+
|              |            |      B2      |      B3      |
+--------------+------------+--------------+--------------+

Попытка сделать столбцы как можно ближе к равномерному масштабу. Но макет представляет собой сетку из 5 строк и 4 столбцов. Верхняя метка L1 будет охватывать все столбцы в первой строке. Два виджета ввода E1 и E2 будут занимать первые 3 столбца в соответствующих строках. По какой-то причине B2 получает меньший размер.

Редактировать: Лучшее, что я могу определить, - это то, что виджет Entry вызывает взвешенные проблемы, но я не знаю, почему. На эту же тему отвечает Брайан Оукли здесь , но меня смущает вопрос, почему ширина по умолчанию для виджета не перезаписывается ключевым словом weight менеджера сетки.

1 Ответ

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

Вопрос : Почему эти кнопки имеют разный размер при использовании одинаковых весов в сетке?

Это только вес, а невычисляется . Это зависит от используемых виджетов и панелей столбцов.
Вы используете sticky='nsew' в целом, измените на sticky='ew', если не хотите увеличиваться до sn.


Один из возможных вариантов:, чтобы использовать различные значения weight=, чтобы дать подсказке Grid Manager подсказку, какой виджет вы хотите, чтобы он был более взвешенным , например:

            f.grid_columnconfigure(0, weight=1)
            f.grid_columnconfigure(1, weight=1)
            f.grid_columnconfigure(2, weight=2)
            f.grid_columnconfigure(3, weight=4)

Другой вариант:использовать .grid_columnconfigure(c, minsize=<minsize>).
Это заставляет Grid Manager подчиняться minsize= для столбца.

Source : tkinter.__init__: def grid_columnconfigure(...
Допустимые ресурсы:

  • minsize (минимальный размер столбца),
  • weight (сколько дополнительного пространства распространяется на этот столбец)
  • pad (сколько места нужно оставитьдополнительно)

Но результаты также не предсказуемы, в лучшем случае при фиксированном размере окна.


Чтобы заставить его работать с изменением размера окна, свяжите событие <Configure> с Frame, и
установите одинаковые , вычисленные minsize= для каждого столбца.

enter image description here enter image description here

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        super().__init__()

        f = tk.Frame(self)
        f.pack(fill=tk.BOTH, expand=True)
        f.bind('<Configure>', self.on_configure)

        ...

    def on_configure(self, event):
        w = event.widget
        columns = w.grid_size()[0]
        minsize = w.winfo_width() // columns

        for c in range(columns):
            w.grid_columnconfigure(c, minsize=minsize)


if __name__ == "__main__":
    App().mainloop()

Протестировано с Python: 3,5 - 'TclVersion': 8,6 'TkVersion ': 8,6

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