ttk.Separator установить длину/ширину

Как установить/изменить длину/ширину объекта ttk.Separator в Tkinter?

        ttk.Separator(self, orient='horizontal').grid(column=0,
        row=0, columnspan=2, sticky='ew')

Кажется, что columnspan пытается выполнить эту работу, но когда у вас есть несколько разделителей с одним и тем же значением columnspan, они имеют разную длину — есть идеи, почему?

Вот простой быстрый пример «грязного» теста:

import ttk
from Tkinter import *

class myTestFrame(Frame):

    def __init__(self):

        Frame.__init__(self)

        self.master.title("My Test Frame")

        self.master.minsize(350, 150)
        self.grid(sticky=W+N+S+E)

        firstLayer      = Frame(self)
        firstLayer.pack(side="top", fill="x")
        secondLayer      = Frame(self)
        secondLayer.pack(side="top", fill="x")
        thirdLayer      = Frame(self)
        thirdLayer.pack(side="top", fill="x")

        labelText=StringVar()
        labelText.set("Enter your area zip code: ")
        labelDir=Label(firstLayer, textvariable=labelText, fg="black", font = "Calibri 10 bold")
        labelDir.grid(row=2, column=0, sticky="W")
        zipCode=IntVar(None)
        entryFieldFrame=Entry(firstLayer,textvariable=zipCode,width=5)
        entryFieldFrame.grid(row=2, column=1, sticky="W", padx=31)

        ttk.Separator(secondLayer, orient='horizontal').grid(column=0,
            row=0, columnspan=2, sticky='ew')

        labelText=StringVar()
        labelText.set("Enter your age: ")
        labelDir=Label(secondLayer, textvariable=labelText, fg="black", font = "Calibri 10 bold")
        labelDir.grid(row=2, column=0, sticky="W")
        age=IntVar(None)
        age.set(1.0)
        entryFieldFrame=Entry(secondLayer,textvariable=age,width=5)
        entryFieldFrame.grid(row=2, column=1, sticky="W", padx=83)

        ttk.Separator(thirdLayer, orient='horizontal').grid(column=0,
            row=0, columnspan=2, sticky='ew')

        labelText=StringVar()
        labelText.set("Enter your brother's age: ")
        labelDir=Label(thirdLayer, textvariable=labelText, fg="black", font = "Calibri 10 bold")
        labelDir.grid(row=2, column=0, sticky="W")
        brothersAge=IntVar(None)
        entryFieldFrame=Entry(thirdLayer,textvariable=brothersAge,width=5)
        entryFieldFrame.grid(row=2, column=1, sticky="W", padx=29)

if __name__ == "__main__":

    testFrame = myTestFrame()
    testFrame.mainloop()

person schmi    schedule 20.06.2016    source источник
comment
columnspan не влияет на ширину сама по себе, она просто определяет, сколько столбцов занимает виджет. Фактическая ширина зависит от размера столбцов.   -  person Bryan Oakley    schedule 20.06.2016
comment
можно ли как-то явно (повторно) определить ширину разделителя, поскольку у меня есть разные столбцы с разной длиной, но я все же хочу иметь разделители с ТАКОЙ же шириной/длиной? Кажется, что опция padx в спецификации grid тоже не помогает.   -  person schmi    schedule 20.06.2016
comment
да и нет. Конечно, вы можете сделать некоторые трюки, например, поместить разделитель в рамку, а затем установить размер рамки, но это редко требуется. Разделители предназначены для разделения элементов и обычно имеют ту же ширину или высоту, что и предметы, которые они разделяют. Кажется, вы используете их для какой-то другой цели, но в вашем вопросе недостаточно информации, чтобы предложить альтернативу. Пожалуйста, дайте mcve (stackoverflow.com/help/mcve), чтобы проиллюстрировать, как вам нужны разделители фиксированной ширины с переменной ширина столбцов.   -  person Bryan Oakley    schedule 20.06.2016
comment
ну, моя установка довольно проста - у меня есть ряды меток и полей ввода (каждый ряд содержит одну метку и поле ввода). Метки в каждом ряду имеют разную длину/ширину - поэтому я хочу сгруппировать некоторые из этих строк с помощью разделителей (которые, надеюсь, будут иметь одинаковую длину) и не использовать кадры - это возможно или я должен использовать Рамки?   -  person schmi    schedule 20.06.2016
comment
пожалуйста, предоставьте mcve. То, что вы хотите сделать, почти наверняка возможно, но не очень ясно, что вы хотите сделать.   -  person Bryan Oakley    schedule 20.06.2016
comment
В примере, какой результат вы хотите? Должны ли разделители идти до конца, только под метками, только под метками и виджетами ввода, ...?   -  person Bryan Oakley    schedule 20.06.2016
comment
Я хочу, чтобы они шли до конца полей ввода   -  person schmi    schedule 20.06.2016
comment
Было бы также неплохо увидеть опцию, позволяющую идти до конца оконной рамы.   -  person schmi    schedule 20.06.2016


Ответы (1)


Ваша проблема не в том, что разделители слишком короткие, а в том, что вы не сказали grid, что делать с дополнительным нераспределенным пространством. Ваши столбцы имеют ровно такую ​​ширину, какая им нужна, а ваш разделитель такой же ширины, как и столбцы, в которых он находится. В комментарии вы говорите: «Я хочу, чтобы они доходили до конца полей ввода», и это именно то, что они делают. На самом деле вам нужно, чтобы все поля ввода заканчивались в одном и том же месте.

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

Быстрое и грязное решение здесь состоит в том, чтобы убедиться, что столбец 0 или 1 получает дополнительное пространство. Обычно выбор заключается в том, чтобы передать его виджету ввода. Итак, вы можете добавить это, чтобы улучшить ситуацию:

thirdLayer.grid_columnconfigure(1, weight=1)

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

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

person Bryan Oakley    schedule 20.06.2016