Как сделать простой мастер с помощью grid() в Tkinter?

Простите меня. Я новичок в Tkinter и имею только простое/скромное понимание python. Моя общая цель состоит в том, чтобы создать программу, похожую на мастер, в которой пользователь вводит все более подробные сведения по мере выполнения программы (с появлением определенных кадров в зависимости от определенных входных данных). Я пытаюсь просто заставить работать основную идею мастера и сталкиваюсь с некоторыми проблемами. Вот мой код (я закомментировал вещи, которые, как предполагают другие источники, находятся на правильном пути, но потерпели неудачу для меня):

from Tkinter import *
root = Tk()
#root.minsize(300,300) ?
#root.geometry("300x300") ?

def next():
    move(+1)

def prev():
    move(-1)

def exit_program():
    root.destroy()

page1 = Frame(root, width=300, height=300)
page1.grid()
#page1.grid(row=0,column=0, sticky="nsew") ?
#page1.grid_rowconfigure(0, weight=1) ?
#page1.grid_columnconfigure(0, weight=1) ?
p1_label = Label(page1, text='This is page 1 of the wizard.').grid(column=1, row=0)
p1_quit = Button(page1, text="Quit", command=exit_program).grid(column=1, row=2)
p1_next = Button(page1, text="Next", command=next).grid(column=2, row=2)

page2 = Frame(root)
p2_label = Label(page2, text='This is page 2 of the wizard.').grid(column=1, row=0)
p2_prev = Button(page2, text="Prev", command=prev).grid(column=1, row=2)
p2_next = Button(page2, text="Next", command=next).grid(column=2, row=2)

page3 = Frame(root)
p3_label = Label(page3, text='This is page 3 of the wizard.').grid(column=1, row=0)
p3_prev = Button(page3, text="Prev", command=prev).grid(column=1, row=2)
p3_quit = Button(page3, text="Quit", command=exit_program).grid(column=2, row=2)

pages = [page1, page2, page3]
current = page1
def move(dirn):
    global current
    idx = pages.index(current) + dirn
    if not 0 <= idx < len(pages):
        return
   current.grid_forget()
   current = pages[idx]
   current.grid()

root.mainloop()

У меня есть несколько вопросов:

  • Почему первый (и все) фреймы сжимаются до размера виджетов внутри, хотя я установил ширину и высоту на определенную величину? Я посмотрел в Интернете и, по-видимому, grid_propagate(False) отключает изменение размера, но это и настоятельно НЕ рекомендуется, и совершенно безуспешно (да, это делает окно нужным мне размером, но сама «сетка» все еще находится в верхнем -оставил). Разве я не могу указать размеры кадра, и сетка выравнивается по этим размерам (т. е. сохраняется организация сетки, а не область)? Связана ли эта проблема с процессом мастера? Я бы тоже не хотел, но я, вероятно, все еще могу написать программу в одном окне.
  • Почему сетка выглядит как 2x2? Разве это не должно быть 3x3, потому что нулевая запись действительна? Я разместил кнопку (p1_next) в позиции (2x2). Это потому, что в столбце 0 ничего нет, grid() удаляет его и сдвигает все влево?
  • Является ли это лучшим подходом к тому, чего я пытаюсь достичь? Боюсь, я знаю только абсолютные основы ООП и предпочел бы избегать, если это возможно (также эта программа, хотя и большая для меня, в конечном итоге окажется крошечной по современным стандартам разработки программного обеспечения).

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

Извините, если это дубликат. И спасибо!


person J. Davis    schedule 09.10.2015    source источник


Ответы (1)


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

Просто так работает tkinter: контейнеры сжимаются, чтобы соответствовать их содержимому. В 99% случаев это правильное решение. Как вы заметили, вы можете отключить распространение геометрии, но это имеет побочные эффекты и требует от вас выполнения работы, с которой обычно лучше справляется tkinter. Если вы действительно настаиваете на том, чтобы кадр был определенного размера, обычно вы отключаете распространение.

Если ваш конкретный случай, имеет смысл заставить главное окно иметь определенный размер, а не кадры определенного размера. Затем рамки будут увеличиваться (или уменьшаться) по размеру главного окна. Вы можете сделать это, используя метод geometry корневого окна.

Почему сетка выглядит как 2x2? Разве это не должно быть 3x3, потому что нулевая запись действительна? Я разместил кнопку (p1_next) в позиции (2x2). Это потому, что в столбце 0 ничего нет, grid() удаляет его и сдвигает все влево?

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

Является ли это лучшим подходом к тому, чего я пытаюсь достичь?

Трудно ответить. Вероятно, нет «лучшего» способа.

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

person Bryan Oakley    schedule 09.10.2015