Сетка и упаковка в Main и Class?

Я только что переместил свой макет в Tkinter из пакета в сетку. Все идет хорошо. Я совершил ошибку, использовав пакет и сетку вместе в своей основной функции. Чиню и не только хватом. Но я понял, что все еще использую pack внутри класса, который также создает виджеты Tkinter. Это все ярлыки. Похоже, это нормально, и это работает, но я не думаю, что это хорошая практика. Если я использую сетку в классе, будет ли она вставлена ​​в сетку основного элемента? Как лучше всего расположить экран, когда некоторые виджеты создаются в классе, а некоторые - в главном?

Итак, вот класс со стаей в нем ....

class StopWatch(Frame):
    ...

    def makeWidgets(self):
        """ Make the time labels. """
        la = Label(self, textvariable=self.timestr)
        la.pack(fill=X, expand=NO, pady=2, padx=2)

        lb = Label(self, textvariable=self.timestr)
        lb.pack(fill=X, expand=NO, pady=2, padx=2)

        lc = Label(self, textvariable=self.timestr)
        lc.pack(fill=X, expand=NO, pady=2, padx=2)

        ld = Label(self, textvariable=self.timestr)
        ld.pack(fill=X, expand=NO, pady=2, padx=2)

        lsplita = Label(self, textvariable=self.lapastr)
        lsplita.pack(fill=X, expand=NO, pady=2, padx=2)

        lsplitb = Label(self, textvariable=self.lapbstr)
        lsplitb.pack(fill=X, expand=NO, pady=2, padx=2)

        lsplitc = Label(self, textvariable=self.lapcstr)
        lsplitc.pack(fill=X, expand=NO, pady=2, padx=2)

        lsplitd = Label(self, textvariable=self.lapdstr)
        lsplitd.pack(fill=X, expand=NO, pady=2, padx=2)

        self._setTime(self._elapsedtime)

Теперь это мой Main с сеткой ....

def main():
    root = Tk()
    root.geometry("500x400")
    sw1 = StopWatch(root)
    sw1.grid(row=0, column=5, rowspan=2)

    b1 = Button(root, text='Start', command=sw1.Start)
    b2 = Button(root, text='Stop', command=sw1.Stop)
    b3 = Button(root, text='Reset', command=sw1.Reset)
    b4 = Button(root, text='Quit', command=root.quit)
    b5 = Button(root, text='Get Split A', command=sw1.Getsplita)
    b6 = Button(root, text='Get Split B', command=sw1.Getsplitb)
    b7 = Button(root, text='Get Split C', command=sw1.Getsplitc)
    b8 = Button(root, text='Get Split D', command=sw1.Getsplitd)
    b1.grid(row=0, column=0)
    b2.grid(row=0, column=1)
    b3.grid(row=0, column=2)
    b4.grid(row=0, column=3)
    b5.grid(row=1, column=0)
    b6.grid(row=1, column=1)
    b7.grid(row=1, column=2)
    b8.grid(row=1, column=3)

    root.mainloop()

person Husar    schedule 18.02.2015    source источник


Ответы (1)


Рекомендуется использовать в приложении оба grid и pack.

Единственное предостережение - вы не можете смешивать их в одном кадре. Выбор диспетчера геометрии (grid, pack, place) для виджетов в кадре полностью не зависит от диспетчера геометрии, используемого в любом другом кадре. У каждого есть свои сильные и слабые стороны, и вы должны использовать их соответственно.

Также - и я все время вижу эту ошибку - класс, который наследуется от виджета, не должен не вызывать grid, pack или place сам по себе.

Например, это неверно:

class Example(tk.Frame):
    def __init__(self, parent):
        ...
        self.pack(...)

class Main(tk.Frame):
    def __init__(self, parent):
        ...
        this.example = Example(self)

Вместо указанного выше pack следует удалить из Example, а Main следует переопределить для вызова pack (или grid, или place):

class Main(tk.Frame):
    def __init__(self, parent):
        ...
        this.example = Example(self)
        this.example.pack(...)

Проблема с первым (неправильным) примером заключается в том, что если у вас есть дюжина фреймов внутри main вместе с некоторыми другими виджетами, если вы решите переключиться с pack на grid, вам придется изменить дюжину других классов. Имея родителя, ответственного за организацию собственных дочерних элементов, при изменении макета вам нужно изменить только одну функцию.

person Bryan Oakley    schedule 18.02.2015
comment
Как всегда, у вас много информации. Это действительно помогает, поэтому БОЛЬШОЕ спасибо. - person Husar; 19.02.2015
comment
@Husar: Меня прокляло глубокое знание того, что почти никто больше не использует ‹shrug›. Рад, что смог помочь. - person Bryan Oakley; 19.02.2015