В текстовом поле Tkinter скролинг сжимает виджет в ширину - как исправить?
Пишу приложение, в котором необходимо добавить Scrollbar. Сделал это, но теперь получается, что если привязать скролинг к собственно текстовой области (а не к фрейму, в котором она располагается), то область в рамке становится узкой, не растягиваясь по всему фрейму. Как исправить?
window = tk.Tk()
# создадим рамку, которая формирует область с "обучением" модели "вручную"
frame_training = tk.Frame(
master=window,
relief=tk.RIDGE,
borderwidth=5)
# создадим ярлык с заголовком для текстового поля (оно ниже)
lbl_add_to_the_list = tk.Label(
master=frame_training,
text='Дополни список ответов шара',
foreground='black',
bg='#E1D1E0',
width=15,
height=5
)
# данная область предназначена для внесения новых вариантов ответов
text_box_train = tk.Text(
master=frame_training,
width=90,
height=5,
bg='#EBF1F2',
fg='black'
)
# создадим элемент кнопки Обучить шар
button_train = tk.Button(
master=frame_training,
text='Обучить шар',
width=15,
height=2,
bg='#B533FF',
fg='yellow',
activebackground='#C4B1C3'
)
# создадим элемент кнопки Очистить (для обучения шара)
button_train_clear = tk.Button(
master=frame_training,
text='Очистить',
width=15,
height=2,
bg='#B533FF',
fg='yellow',
activebackground='#C4B1C3')
# добавляем виджеты в сетку окна
frame_training.grid(
column=0, row=1,
columnspan=2,
sticky='e')
lbl_add_to_the_list.grid(
sticky='nsew', columnspan=3)
text_box_train.grid(
column=0, row=1,columnspan=3,
sticky='e')
button_train.grid(
row=3, column=0, sticky='e')
button_train_clear.grid(
row=3, column=1, sticky='w', columnspan=2)
# лента прокрутки для текстового поля "обучения" шара
scrollbar_train = tk.Scrollbar(text_box_train,
orient='vertical',
command=text_box_train.yview
)
scrollbar_train.grid(row=1, column=3, sticky='ns')
text_box_train.configure(yscrollcommand=scrollbar_train.set)
Ответы (1 шт):
Одним grid тут не обойтись, ибо в разных рядах вам нужна разная сетка. Опять же, способов уйма как достичь требуемого. Надо использовать вложенные фреймы. Можно на pack, можно и на grid (хотя лично я предпочитаю, где это возможно, использовать pack, выглядит, как по мне, понятнее, да и писанины меньше, если потребуется вдруг чего добавить/убрать/переставить).
Вот так это можно реализовать на grid:
import tkinter as tk
window = tk.Tk()
# создадим рамку, которая формирует область с "обучением" модели "вручную"
frame_training = tk.Frame(
master=window,
relief=tk.RIDGE,
borderwidth=5)
# создадим ярлык с заголовком для текстового поля (оно ниже)
lbl_add_to_the_list = tk.Label(
master=frame_training,
text='Дополни список ответов шара',
foreground='black',
bg='#E1D1E0',
width=15,
height=5
)
frame_training_text_with_scroll = tk.Frame(
master=frame_training
)
# данная область предназначена для внесения новых вариантов ответов
text_box_train = tk.Text(
master=frame_training_text_with_scroll,
width=90,
height=5,
bg='#EBF1F2',
fg='black'
)
# создадим элемент кнопки Обучить шар
button_train = tk.Button(
master=frame_training,
text='Обучить шар',
width=15,
height=2,
bg='#B533FF',
fg='yellow',
activebackground='#C4B1C3'
)
# создадим элемент кнопки Очистить (для обучения шара)
button_train_clear = tk.Button(
master=frame_training,
text='Очистить',
width=15,
height=2,
bg='#B533FF',
fg='yellow',
activebackground='#C4B1C3')
# добавляем виджеты в сетку окна
frame_training.grid(
column=0, row=0,
columnspan=2,
sticky='nswe')
window.grid_rowconfigure(0, weight=1)
window.grid_columnconfigure(0, weight=1)
lbl_add_to_the_list.grid(
row=0, column=0, columnspan=2,
sticky='nsew')
frame_training_text_with_scroll.grid(
row=1, column=0, columnspan=2,
sticky='news')
frame_training.grid_rowconfigure(1, weight=1)
frame_training.grid_columnconfigure(0, weight=1)
frame_training.grid_columnconfigure(1, weight=1)
text_box_train.grid(
row=0, column=0,
sticky='news')
frame_training_text_with_scroll.grid_rowconfigure(0, weight=1)
frame_training_text_with_scroll.grid_columnconfigure(0, weight=1)
button_train.grid(
row=2, column=0, sticky='ew')
button_train_clear.grid(
row=2, column=1, sticky='ew',)
# лента прокрутки для текстового поля "обучения" шара
scrollbar_train = tk.Scrollbar(master=frame_training_text_with_scroll,
orient='vertical',
command=text_box_train.yview
)
scrollbar_train.grid(row=0, column=2, sticky='ns')
text_box_train.configure(yscrollcommand=scrollbar_train.set)
text_box_train.insert(tk.END, "Line1\nLine2\nLine3\nLine4\nLine5\nLine6\nLine7\nLine8\n")
window.mainloop()
Или то же самое, используя pack:
import tkinter as tk
window = tk.Tk()
# создадим рамку, которая формирует область с "обучением" модели "вручную"
frame_training = tk.Frame(
master=window,
relief=tk.RIDGE,
borderwidth=5)
# создадим ярлык с заголовком для текстового поля (оно ниже)
lbl_add_to_the_list = tk.Label(
master=frame_training,
text='Дополни список ответов шара',
foreground='black',
bg='#E1D1E0',
width=15,
height=5
)
frame_training_text_with_scroll = tk.Frame(
master=frame_training
)
# данная область предназначена для внесения новых вариантов ответов
text_box_train = tk.Text(
master=frame_training_text_with_scroll,
width=90,
height=5,
bg='#EBF1F2',
fg='black'
)
frame_buttons = tk.Frame(
master=frame_training
)
# создадим элемент кнопки Обучить шар
button_train = tk.Button(
master=frame_buttons,
text='Обучить шар',
width=15,
height=2,
bg='#B533FF',
fg='yellow',
activebackground='#C4B1C3'
)
# создадим элемент кнопки Очистить (для обучения шара)
button_train_clear = tk.Button(
master=frame_buttons,
text='Очистить',
width=15,
height=2,
bg='#B533FF',
fg='yellow',
activebackground='#C4B1C3')
# добавляем виджеты в сетку окна
frame_training.pack(fill=tk.BOTH, expand=True)
lbl_add_to_the_list.pack(fill=tk.X)
frame_training_text_with_scroll.pack(fill=tk.BOTH, expand=True)
text_box_train.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
frame_buttons.pack(fill=tk.X)
button_train.pack(side=tk.LEFT, fill=tk.X, expand=True)
button_train_clear.pack(side=tk.LEFT, fill=tk.X, expand=True)
# лента прокрутки для текстового поля "обучения" шара
scrollbar_train = tk.Scrollbar(master=frame_training_text_with_scroll,
orient='vertical',
command=text_box_train.yview
)
scrollbar_train.pack(side=tk.LEFT, fill=tk.Y)
text_box_train.configure(yscrollcommand=scrollbar_train.set)
text_box_train.insert(tk.END, "Line1\nLine2\nLine3\nLine4\nLine5\nLine6\nLine7\nLine8\n")
window.mainloop()
