Положение текста во фрейме — Python

#python-2.7 #tkinter

#python-2.7 #tkinter

Вопрос:

Я ищу способ расположить свой текст в центре моего графического интерфейса. Когда окно графического интерфейса расширяется, текст должен оставаться центрированным.

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

Есть предложения?

 from Tkinter import *
import ttk
import csv


master = Tk()
master.option_add("*Font", "{Bodoni MT} 8")

content = ttk.Frame(master, padding=(12, 12, 12, 12))
frame = ttk.Frame(content, borderwidth=5, relief="groove", width=300, height=100)
content.grid(column=0, row=0, sticky=(N, S, E, W))
frame.grid(column=0, row=0, columnspan=4, sticky=(N, E, W))
text = Text(content, height=8, width=13)
text.grid(row=0, column=4, columnspan=2, rowspan=2, sticky=(N, S, E, W))


v1surface = StringVar()
v2surface = StringVar()
v1tournament = StringVar()
v2tournament = StringVar()

empty_row = Label(frame).grid(column=1, padx=100, sticky=(N, E, W))
surface_title = Label(frame, text="Surface", font="{Bodoni MT} 12 bold underline").grid(row=1, column=2, columnspan=2)
surface_selection = Label(frame, text="Select Surface:").grid(row=2, column=2, sticky='w')
a_surface = Label(frame, text="Service Points Win %:").grid(row=3, column=2, sticky='w')
aa_surface = Entry(frame, text="value", textvariable=v1surface, justify='center', width=10).grid(row=3, column=3)
b_surface = Label(frame, text="Return Points Win %: ").grid(row=4, column=2, sticky='w')
bb_surface = Entry(frame, text="value", textvariable=v2surface, justify='center', width=10).grid(row=4, column=3)


tournament_title = Label(frame, text="Tournament", font="{Bodoni MT} 12 bold underline")
    .grid(row=1, column=5, columnspan=2)
tournament_selection = Label(frame, text="Select Tournament:").grid(row=2, column=5, sticky='w')
a_tournament = Label(frame, text="Service Points Win %:").grid(row=3, column=5, sticky='w')
aa_tournament = Entry(frame, text="value", textvariable=v1tournament, justify='center', width=10).grid(row=3, column=6)
b_tournament = Label(frame, text="Return Points Win %: ").grid(row=4, column=5, sticky='w')
bb_tournament = Entry(frame, text="value", textvariable=v2tournament, justify='center', width=10).grid(row=4, column=6)



run = ttk.Button(content, text='Run')
run.grid(column=4, row=3)
cancel = ttk.Button(content, text="Cancel", command=master.destroy)
cancel.grid(column=5, row=3)

master.columnconfigure(0, weight=1)
master.rowconfigure(0, weight=1)
content.columnconfigure(0, weight=3)
content.columnconfigure(1, weight=3)
content.columnconfigure(2, weight=3)
content.columnconfigure(3, weight=1)
content.columnconfigure(4, weight=1)
content.rowconfigure(1, weight=1)

master.geometry("1000x500 100 100")
master.mainloop()
  

Комментарии:

1. Какой текст вы хотите центрировать? Я вижу много меток. Вы хотите, чтобы виджеты ввода также были центрированы? Ваше описание очень расплывчатое.

2. @BryanOakley, я хочу, чтобы все метки и виджеты ввода в «фрейме» были центрированы

3. Вы хотите, чтобы фрейм, в котором они находятся, также был центрирован? Или вы хотите, чтобы фрейм был вверху, а виджеты внутри были центрированы в фрейме?

4. Я хочу, чтобы фрейм оставался таким, какой он есть, поэтому виджеты должны быть центрированы в фрейме

Ответ №1:

Есть много способов добиться того, чего вы хотите.

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

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

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

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

Обратите внимание, что я добавил один новый виджет, inner_frame , и удалил один виджет, empty_row . Затем я центрировал внутренний фрейм внутри другого фрейма (того, который назван frame ). Наконец, я установил родительский элемент всех меток и записей как внутренний фрейм.

 from Tkinter import *
import ttk
import csv

master = Tk()
master.option_add("*Font", "{Bodoni MT} 8")

content = ttk.Frame(master, padding=(12, 12, 12, 12), borderwidth=2, relief="groove")
frame = ttk.Frame(content, borderwidth=5, relief="groove", width=300, height=100)
text = Text(content, height=8, width=13)


v1surface = StringVar()
v2surface = StringVar()
v1tournament = StringVar()
v2tournament = StringVar()

inner_frame = Frame(frame)

surface_title = Label(inner_frame, text="Surface", font="{Bodoni MT} 12 bold underline")
surface_selection = Label(inner_frame, text="Select Surface:")
a_surface = Label(inner_frame, text="Service Points Win %:")
aa_surface = Entry(inner_frame, text="value", textvariable=v1surface, justify='center', width=10)
b_surface = Label(inner_frame, text="Return Points Win %: ")
bb_surface = Entry(inner_frame, text="value", textvariable=v2surface, justify='center', width=10)

tournament_title = Label(inner_frame, text="Tournament", font="{Bodoni MT} 12 bold underline")
    .grid(row=1, column=5, columnspan=2)
tournament_selection = Label(inner_frame, text="Select Tournament:").grid(row=2, column=5, sticky='w')
a_tournament = Label(inner_frame, text="Service Points Win %:").grid(row=3, column=5, sticky='w')
aa_tournament = Entry(inner_frame, text="value", textvariable=v1tournament, justify='center', width=10).grid(row=3, column=6)
b_tournament = Label(inner_frame, text="Return Points Win %: ").grid(row=4, column=5, sticky='w')
bb_tournament = Entry(inner_frame, text="value", textvariable=v2tournament, justify='center', width=10).grid(row=4, column=6)

run = ttk.Button(content, text='Run')
cancel = ttk.Button(content, text="Cancel", command=master.destroy)

# main layout
content.grid(column=0, row=0, sticky=(N, S, E, W))

frame.grid(column=0, row=0, columnspan=4, sticky=(N, E, W))
text.grid(row=0, column=4, columnspan=2, rowspan=2, sticky=(N, S, E, W))
run.grid(column=4, row=3)
cancel.grid(column=5, row=3)

# inner frame, used for centering
inner_frame.place(relx=.5, rely=.5, anchor="c")

# widgets in the inner frame
surface_title.grid(row=1, column=2, columnspan=2)
surface_selection.grid(row=2, column=2, sticky='w')
a_surface.grid(row=3, column=2, sticky='w')
aa_surface.grid(row=3, column=3)
b_surface.grid(row=4, column=2, sticky='w')
bb_surface.grid(row=4, column=3)

master.columnconfigure(0, weight=1)
master.rowconfigure(0, weight=1)
content.columnconfigure(0, weight=3)
content.columnconfigure(1, weight=3)
content.columnconfigure(2, weight=3)
content.columnconfigure(3, weight=1)
content.columnconfigure(4, weight=1)
content.rowconfigure(1, weight=1)

master.geometry("1000x500 100 100")
master.mainloop()