Я новичок в tkinter и учусь создавать простые виджеты. Я столкнулся с проблемой, когда я создавал много кнопок для нажатия, я обнаружил, что расстояние между кнопками неравномерно и становится более перегруженным, когда оно идет слева направо.
Как сделать расстояние между кнопками одинаковым?
%%writefile a.py
import sys
import tkinter as tk
from tkinter import ttk,messagebox
win = tk.Tk()
def countdown(win):
child = tk.Toplevel(win)
child.geometry('400x300')
child.resizable(0, 0)
# label: current time title
tk.Label(child, font='arial 15 bold', text='current time :').place(x=40, y=70)
tk.Label(child, font='arial 15 bold', text='set the time').place(x=40, y=150)
tk.Label(child,text='',fg='gray25').place(x=190, y=70)
frame_top = tk.Frame(child)
frame_top.pack(expand=False, fill=tk.X)
frame_bottom = tk.Frame(child)
frame_bottom.pack(expand=False, fill=tk.X)
mins = [1,2,5,10,15,20,25,30,35,40]
for i,minn in enumerate(mins):
tk.Button(frame_top,text=str(minn)+'m',bd='5',).pack(expand=True, side=tk.LEFT)
for i,minn in enumerate([45,50,55,60,90,120,150,180]):
tk.Button(frame_bottom,text=str(minn)+'m',bd='5',).pack(expand=True, side=tk.LEFT)
menubar = tk.Menu(win)
menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label = "Scripts", menu=menu)
menu.add_command(label='Countdown',command=lambda : countdown(win))
menu.add_command(label='Exit',command=sys.exit)
win.config(menu=menubar)
win.mainloop()
place
— самый сложный способ выполнить эту задачу. Почему вы хотите использовать place
?
Я слышал, что .grid не работает для дочерних окон, поэтому я использую .place.
Я слышал, что .grid не работает для дочернего окна" - это совершенно неверная информация. Все менеджеры геометрии работают во всех типах виджетов.
Вам будет намного проще использовать другой менеджер геометрии, такой как pack()
или, что еще лучше, grid()
Использование pack
:
import tkinter as tk
child = tk.Tk()
child.geometry('400x300')
x,w = 0,40
mins = [1,2,5,10,15,20,25,30,35,40]
mins2 = [45,50,55,60,90,120,150,180]
# create some frames to contain each row of buttons
frame_top = tk.Frame(child)
frame_top.pack(expand=False, fill=tk.X)
frame_bottom = tk.Frame(child)
frame_bottom.pack(expand=False, fill=tk.X)
for minn in (mins):
button = tk.Button(frame_top, text=str(minn)+'m', bd='5')
button.pack(expand=True, side=tk.LEFT)
for minn in (mins2):
button = tk.Button(frame_bottom, text=str(minn)+'m', bd='5')
button.pack(expand=True, side=tk.LEFT)
child.mainloop()
Использование grid
:
import tkinter as tk
child = tk.Tk()
child.geometry('400x300')
x,w = 0,40
mins = [1,2,5,10,15,20,25,30,35,40]
mins2 = [45,50,55,60,90,120,150,180]
for i, min in enumerate(mins):
button = tk.Button(child, text=str(minn)+'m', bd='5')
button.grid(row=0, column=i)
for i, minn in enumerate(mins2):
button = Button(child, text=str(minn)+'m', bd='5')
button.grid(row=1, column=i)
child.mainloop()
По общему признанию, я лучше всех знаком с pack()
— если кто-то увидит проблему с моей реализацией grid()
, обязательно дайте мне знать!
Приложение
Обычно целесообразно создавать экземпляры виджетов отдельно от добавления их в менеджер геометрии, например pack
, place
или grid
.
# DON'T:
button = ttk.Button(parent).pack()
# button = None
# DO:
button = ttk.Button(parent) # instantiate widget
button.pack() # pack separately
# button = .!button
Причина объясняется здесь, но суть в том, что методы менеджера геометрии возвращают None
, и это может вызвать проблемы, если вы не обращаете внимания.
Это здорово, это также работает для моего обновленного вопроса?
Должен, да - основная идея та же самая
Я заменил .place
на .pack(expand=True, side=tk.LEFT)
и получил вывод, как показано в обновленном вопросе. Как управлять этим в два ряда?
Если вы используете pack()
, вам нужно создать несколько Frame
, которые будут действовать как контейнеры для каждого ряда кнопок, как я описал в своем первом примере.
.place()
на самом деле не лучший инструмент для этой работы. Научитесь использовать.pack()
или.grid()
, они делают гораздо больше работы за вас.