Добавление вертикальной полосы прокрутки в tkinter python [duplicate]

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

Документация подразумевает, что только виджеты List, Textbox, Canvas и Entry поддерживают интерфейс прокрутки. Ни один из них не подходит для отображения сетки виджетов. Можно добавить произвольные виджеты в виджет Canvas, но вам, похоже, придется использовать абсолютные координаты, поэтому я не смогу использовать диспетчер компоновки сетки?

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

mainframe = Frame(root, yscrollcommand=scrollbar.set)

Может ли кто-нибудь предложить способ обойти это ограничение? Мне бы очень не хотелось переписывать в PyQt и увеличить размер исполняемого изображения настолько, чтобы добавить прокрутку!

47
задан 11 December 2015 в 04:04

1 ответ

Сделать это прокручиваемым

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

создайте отображение кадра (пакет, сетка и т. Д.), Сделав его прокручиваемым, добавив в него виджеты, вызывая метод update ()
import tkinter as tk
from tkinter import ttk

class Scrollable(ttk.Frame):
    """
       Make a frame scrollable with scrollbar on the right.
       After adding or removing widgets to the scrollable frame, 
       call the update() method to refresh the scrollable area.
    """

    def __init__(self, frame, width=16):

        scrollbar = tk.Scrollbar(frame, width=width)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y, expand=False)

        self.canvas = tk.Canvas(frame, yscrollcommand=scrollbar.set)
        self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        scrollbar.config(command=self.canvas.yview)

        self.canvas.bind('<Configure>', self.__fill_canvas)

        # base class initialization
        tk.Frame.__init__(self, frame)         

        # assign this obj (the inner frame) to the windows item of the canvas
        self.windows_item = self.canvas.create_window(0,0, window=self, anchor=tk.NW)


    def __fill_canvas(self, event):
        "Enlarge the windows item to the canvas width"

        canvas_width = event.width
        self.canvas.itemconfig(self.windows_item, width = canvas_width)        

    def update(self):
        "Update the canvas and the scrollregion"

        self.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox(self.windows_item))

Пример использования

root = tk.Tk()

header = ttk.Frame(root)
body = ttk.Frame(root)
footer = ttk.Frame(root)
header.pack()
body.pack()
footer.pack()

ttk.Label(header, text="The header").pack()
ttk.Label(footer, text="The Footer").pack()


scrollable_body = Scrollable(body, width=32)

for i in range(30):
    ttk.Button(scrollable_body, text="I'm a button in the scrollable frame").grid()

scrollable_body.update()

root.mainloop()
0
ответ дан 15 August 2018 в 16:46
  • 1
    Я получаю ошибку в привязке, что она не привязана ни к чему, поэтому я попробовал ее с помощью & quot; & lt; Configure & gt; & quot ;. Тогда он работает, но заканчивается неправильным размером ... как сделать прокручиваемую рамку заполнять все пространство родителя и динамически изменять размер? – samkass 11 February 2018 в 01:20
  • 2
    Спасибо @samkass, добавив & quot; & lt; Configure & gt; & quot; правильно, это была опечатка. – Tarqez 11 February 2018 в 14:29
  • 3
    Добавить параметры: body.pack (fill = tk.BOTH, expand = True) – Tarqez 26 March 2018 в 21:03

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

Похожие вопросы: