Python & ttk с использованием labelFrames для очистки кадра

Я пытаюсь построить базовый GUI с помощью ttk / Tkinter.

у меня есть базовый графический интерфейс, который имеет правильные базовые компоненты, но когда я пытаюсь его / пространство, я достигаю предела получения контейнеров ttk, чтобы играть красиво...

примеры:

from Tkinter import *
import ttk

class MakeGUI(object):
    def __init__(self,root):
        self.root = root
        self.root.title("Text Comparitor")
        ## build frame
        self.mainframe = ttk.Frame(self.root, padding="3 3 12 12")
        self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
        self.mainframe.columnconfigure(0, weight=1)
        self.mainframe.rowconfigure(0, weight=1)
        self.mainframe.pack()
        ## text labels
        ttk.Label(self.mainframe, text="Conversion Truth Tester", font=("Helvetica", 32)).grid(column=1, row=1, sticky=E)
        self.mainframe.pack(side="bottom", fill=BOTH, expand=True)
        self.mainframe.grid()
        ttk.Label(self.mainframe, text="Source Filename:").grid(column=1, row=2, sticky=W)
        ttk.Label(self.mainframe, text="Source Text:").grid(column=1, row=3, sticky=W)
        ttk.Label(self.mainframe, text="Converted Text:").grid(column=1, row=4, sticky=W)
        ttk.Label(self.mainframe, text="Cleaned Source:").grid(column=1, row=5, sticky=W)
        ttk.Label(self.mainframe, text="Cleaned Converted:").grid(column=1, row=6, sticky=W)
        ttk.Label(self.mainframe, text="Details:").grid(column=1, row=7, sticky=W)
        ## buttons
        self.close = ttk.Button(self.mainframe, text="Close",command=self.closeFrame).grid(column=1, row=9, sticky=SE)
        self.next = ttk.Button(self.mainframe, text="Next",command=self.nextPara).grid(column=1, row=9, sticky=S)
        self.next = ttk.Button(self.mainframe, text="Prev",command=self.prevPara).grid(column=1, row=9, sticky=SW)

    def closeFrame(self):
        self.root.destroy()

    def nextPara(self):
        pass

    def prevPara(self):
        pass

def main():
    root = Tk()
    makeGUI = MakeGUI(root)
    root.mainloop()

if __name__ == '__main__':
    main()

что приводит к: http://imgur.com/a/CwpCU#0

Я пытался добавить 2-й объект контейнера, рамку метки для хранения объектов текстовой метки, что приводит к перемещению кнопок далее (и поэтому я предполагаю, что я не ссылаюсь на labelframe в сетку должным образом:

from Tkinter import *
import ttk

class MakeGUI(object):
    def __init__(self,root):
        self.root = root
        self.root.title("Text Comparitor")
        ## build frame
        self.mainframe = ttk.Frame(self.root, padding="3 3 12 12")
        self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
        self.mainframe.columnconfigure(0, weight=1)
        self.mainframe.rowconfigure(0, weight=1)
        self.mainframe.pack()
        ## text labels
        ttk.Label(self.mainframe, text="Conversion Truth Tester", font=("Helvetica", 32)).grid(column=1, row=1, sticky=E)
        self.lfdata = ttk.Labelframe(self.root, labelwidget=self.mainframe, text='Label')#
        self.lfdata.grid()
        ttk.Label(self.lfdata, text="Source Filename:").grid(column=1, row=2, sticky=W)
        ttk.Label(self.lfdata, text="Source Text:").grid(column=1, row=3, sticky=W)
        ttk.Label(self.lfdata, text="Converted Text:").grid(column=1, row=4, sticky=W)
        ttk.Label(self.lfdata, text="Cleaned Source:").grid(column=1, row=5, sticky=W)
        ttk.Label(self.lfdata, text="Cleaned Converted:").grid(column=1, row=6, sticky=W)
        ttk.Label(self.lfdata, text="Details:").grid(column=1, row=7, sticky=W)

        ## buttons
        self.close = ttk.Button(self.mainframe, text="Close",command=self.closeFrame).grid(column=1, row=9, sticky=SE)
        self.next = ttk.Button(self.mainframe, text="Next",command=self.nextPara).grid(column=1, row=9, sticky=S)
        self.next = ttk.Button(self.mainframe, text="Prev",command=self.prevPara).grid(column=1, row=9, sticky=SW)

    def closeFrame(self):
        self.root.destroy()

    def nextPara(self):
        pass

    def prevPara(self):
        pass

def main():
    root = Tk()
    makeGUI = MakeGUI(root)
    root.mainloop()

if __name__ == '__main__':
    main()

что приводит к: http://imgur.com/a/CwpCU#1 обратите внимание на обмен позициями между кнопками ABD labels и почти видимыми аспектами labelframe.

Я пытаюсь заставить 2-ю версию "выглядеть" как более красивая версия 1-й.

любые указатели-я читал вокруг различных ресурсов / документов и не могу найти ничего, что соответствует моему примеру (скорее всего - Я делаю какую-то глупость...) и ничего, что я пробовал, еще не сработало-включая pack(), grid() и другие фрагменты, которые я нашел в других соответствующих примеров.

1 ответов


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

прежде всего, применение Весов к столбцам/строкам только в рамке не заставит его расширяться при изменении размера окна. Вам нужно сделать это в root. После этого вы можете сделать это в кадре, чтобы соответствовать вашим ожиданиям о макете после изменения размера. В вашем случае, то, что имеет смысл, делает каждый столбец имеет тот же вес > 0, и только вторая строка имеет вес > 0. Аргументация для столбцов заключается в том, что у вас есть 3 кнопки, и вы хотите, чтобы все они расширялись в свободном пространстве одинаково. Во второй части это прямое наблюдение, учитывая, что у вас есть Labelframe во втором ряду. Предоставление веса > 0 для любой другой строки даст вам очень странный макет. Взвешивание вопросов сделано.

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

теперь Labelframe создать. Это просто неправильно,labelwidget опция не означает то, что вы думаете, что она делает. Он указывает Label виджет, который будет служить меткой для этой рамки метки. Таким образом, указание основного фрейма для этого параметра не имеет смысла. Возможно, вы хотите указать текст, который будет виден в определенной позиции в рамке метки. Кроме того, эта рамка этикетка должна быть grided с columnspan значение из 3 тоже.

для "сетки" вообще рекомендую указать опцию in_, так что вы ясно по отношению к тому, что виджет вы "gridding". С этого, становится очевидным, чтобы начать на column=0, row=0 каждый раз, когда вы углубляете свой уровень родительского виджета.

вот как я настроил ваш код:

import Tkinter
import ttk

class MakeGUI(object):
    def __init__(self,root):
        self.root = root
        self.root.title(u"Title")
        ## build frame
        self.mainframe = ttk.Frame(self.root, padding=(6, 6, 12, 12))
        self.mainframe.grid(sticky='nwse')
        for column in range(3):
            self.mainframe.columnconfigure(column, weight=1)
        self.mainframe.rowconfigure(1, weight=1)

        ## text labels
        ttk.Label(self.mainframe, text=u"Label Title", anchor='center',
                font=("Helvetica", 32)).grid(in_=self.mainframe,
                        column=0, row=0, columnspan=3, sticky="ew")

        self.lfdata = ttk.Labelframe(self.mainframe, padding=(6, 6, 12, 12),
                text='Labelframe')
        self.lfdata.grid(column=0, columnspan=3, row=1, sticky='nsew')
        info = (u"Source Filename", u"Source Text", u"Converted Text",
                u"Cleaned Source", u"Cleaned Converted", u"Details")
        for i, item in enumerate(info):
            ttk.Label(self.lfdata, text=u"%s:" % item).grid(in_=self.lfdata,
                    column=0, row=i, sticky='w')

        ## buttons
        btn = (u"Close", u"Next", u"Prev")
        for i, item in enumerate(btn):
            ttk.Button(self.mainframe, text=item).grid(in_=self.mainframe,
                    column=i, row=3)

def main():
    root = Tkinter.Tk()
    root.columnconfigure(0, weight=1)
    root.rowconfigure(0, weight=1)
    makeGUI = MakeGUI(root)
    root.mainloop()

if __name__ == '__main__':
    main()

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

enter image description hereenter image description here