Прокрутка текстового виджета не работает внутри Frame

Это очень странно, и мне интересно, есть ли какое-нибудь исправление, кроме «добавить дополнительное пространство внизу» Вот пример кода, объясняющий, что я делаю:

from tkinter import *

root = Tk()
root.geometry("100x300")

scrollbar = Scrollbar(root)
scrollbar.pack( side = RIGHT, fill=Y )

box = Text(root, wrap = "char", cursor = "arrow", yscrollcommand=scrollbar.set, font=("Helvetica", 30))
box.pack(fill = "both", expand=True)
scrollbar.config( command = box.yview )
scrollbar.lift()

for i in range(5):
    box.insert(INSERT, f"Button {i+1} ")

root.mainloop()

Это работает потрясающе, и вот как выглядит максимальная прокрутка:

Однако, как только я помещаю все в рамку, возникает проблема. Код:

from tkinter import *

root = Tk()
root.geometry("100x400")

frame = Frame(root)
frame.place(x=0, y=100, relwidth=1, relheight=1)

scrollbar = Scrollbar(frame)
scrollbar.pack( side = RIGHT, fill=Y )

box = Text(frame, wrap = "char", cursor = "arrow", yscrollcommand=scrollbar.set, font=("Helvetica", 30))
box.pack(fill = "both", expand=True)
scrollbar.config( command = box.yview )
scrollbar.lift()

for i in range(5):
    box.insert(INSERT, f"Button {i+1} ")

root.mainloop()

И максимальная прокрутка выглядит так:

Как видите, как минимум 2 строки в текстовом виджете были обрезаны, и я понятия не имею, почему. Может ли кто-нибудь помочь?

Часть фрейма находится за пределами видимой области окна, включая виджеты текста и полосы прокрутки. Интересно, почему вы поставили рамку на y=100.

acw1668 06.07.2024 09:12

для Frame вы используете place() и для Scrollbar вы используете pack(), и это может иметь значение.

furas 06.07.2024 16:23

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

Thevin Jayawardena 06.07.2024 18:08

@furas Как именно? Я упаковал полосу прокрутки так, чтобы она прилипала вправо и заполняла букву Y, ни место, ни сетка не могли мне в этом помочь. Я обнаружил, что по умолчанию он придерживается запада или левого края.

Thevin Jayawardena 06.07.2024 18:13

сначала вы помещаете Scroll и Text с pack() прямо в окно - чтобы он автоматически изменял размер/обрезал Scroll и Text до размера окна, но позже вы помещаете его Frame, который использует place() - и вы добавляете y=100 - и place не обрезает его до размера окна размер — поэтому некоторая часть фрейма находится ниже границы окна, и вы не видите полное содержимое. Если Frame будет использовать pack(), он сможет обрезать Frame до высоты окна.

furas 07.07.2024 00:06
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это из-за неправильных настроек геометрии корневого окна и виджета фрейма.

Пример -1:

from tkinter import *

root = Tk()

# Set a more appropriate geometry
root.geometry("600x400")  

# Use the entire root window
frame = Frame(root)
frame.place(x=0, y=0, relwidth=1, relheight=1)  

scrollbar = Scrollbar(frame)
scrollbar.pack(side=RIGHT, fill=Y)

box = Text(frame, wrap = "char", cursor = "arrow", yscrollcommand=scrollbar.set, font=("Helvetica", 30))
box.pack(fill = "both", expand=True)
scrollbar.config(command=box.yview)

for i in range(5):
    box.insert(INSERT, f"Button {i+1} ")

root.mainloop()

Вы можете подумать, что делать, если вы хотите отобразить над рамкой еще один виджет. Решение — использовать pack или grid, чтобы правильно распределить пространство. В следующем примере используется grid, но при этом виджет «Текст» можно прокручивать.

Пример-2

from tkinter import *

root = Tk()
root.geometry("600x400")

# Adding another widget at the top
top_label = Label(root, text = "This is the top label", font=("Helvetica", 16))
top_label.grid(row=0, column=0, columnspan=2, sticky = "ew")

frame = Frame(root)
frame.grid(row=1, column=0, columnspan=2, sticky = "nsew")  # Adjust to fill remaining space

scrollbar = Scrollbar(frame)
scrollbar.pack(side=RIGHT, fill=Y)

box = Text(frame, wrap = "char", cursor = "arrow", yscrollcommand=scrollbar.set, font=("Helvetica", 30))
box.pack(side=LEFT, fill=BOTH, expand=True)
scrollbar.config(command=box.yview)

# Configure the grid to expand properly
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)

for i in range(50):  # Add more lines to test scrolling
    box.insert(INSERT, f"Button {i+1} ")

root.mainloop()

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

Измените для большей ясности:

Используете ли вы grid или pack, имейте приблизительное представление о том, сколько места будет занимать каждый виджет и какова высота и ширина корневого окна. Предположим, что первые 4 виджета занимают 380 пикселей по вертикали, а высота корневого окна равна 400. Таким образом, осталось только 20 пикселей. Если высота вашего пятого виджета превышает 20 пикселей, лишняя высота будет обрезана, даже если вы указали полосу прокрутки.

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

Thevin Jayawardena 06.07.2024 18:25

Зная, что вы могли бы разместить еще один виджет сверху, я привел второй пример. Используете ли вы grid или pack, имейте примерное представление о том, сколько места будет занимать каждый виджет и какова высота и ширина корневого окна. Предположим, что первые 4 виджета занимают 380 пикселей по вертикали, а высота корневого окна равна 400. Таким образом, осталось только 20 пикселей. Если высота вашего пятого виджета превышает 20 пикселей, лишняя высота будет обрезана, даже если вы указали полосу прокрутки.

Suramuthu R 06.07.2024 18:26

Другие вопросы по теме