簡體   English   中英

Python Tkinter可滾動框架類?

[英]Python Tkinter Scrollable Frame Class?

我想根據此處的答案制作一個Tkinter class ,它是一個Frame ,可以根據需要自動在內容周圍顯示/隱藏Scrollbar

我上面鏈接的答案非常適合我的需求,但需要注意的是,由於它不包含在class ,因此不可重用。 我認為這將是非常快速和容易的,但是由於某種原因,一旦我將代碼重構為自己的class ,我的AutoScrollbar不會出現,而不管窗口調整大小隱藏了Frame內容的多少。

# This class is unchanged from the other answer that I linked to,
# but I'll reproduce its source code below for convenience.
from autoScrollbar import AutoScrollbar
from Tkinter       import Button, Canvas, Frame, HORIZONTAL, Tk, VERTICAL

# This is the class I made - something isn't right with it.
class AutoScrollable(Frame):
    def __init__(self, top, *args, **kwargs):
        Frame.__init__(self, top, *args, **kwargs)

        hscrollbar = AutoScrollbar(self, orient = HORIZONTAL)
        hscrollbar.grid(row = 1, column = 0, sticky = 'ew')

        vscrollbar = AutoScrollbar(self, orient = VERTICAL)
        vscrollbar.grid(row = 0, column = 1, sticky = 'ns')

        canvas = Canvas(self, xscrollcommand = hscrollbar.set,
                              yscrollcommand = vscrollbar.set)
        canvas.grid(row = 0, column = 0, sticky = 'nsew')

        hscrollbar.config(command = canvas.xview)
        vscrollbar.config(command = canvas.yview)

        # Make the canvas expandable
        self.grid_rowconfigure(0, weight = 1)
        self.grid_columnconfigure(0, weight = 1)

        # Create the canvas contents
        self.frame = Frame(canvas)
        self.frame.rowconfigure(1, weight = 1)
        self.frame.columnconfigure(1, weight = 1)

        canvas.create_window(0, 0, window = self.frame, anchor = 'nw')
        canvas.config(scrollregion = canvas.bbox('all'))

# This is an example of using my new class I defined above.
# It's how I know my class isn't working quite right.
root = Tk()
autoScrollable = AutoScrollable(root)
autoScrollable.grid(row = 0, column = 0, sticky = 'news')
root.rowconfigure(0, weight = 1)
root.columnconfigure(0, weight = 1)

for i in xrange(10):
    for j in xrange(10):
        button = Button(autoScrollable.frame, text = '%d, %d' % (i, j))
        button.grid(row = i, column = j, sticky = 'news')

autoScrollable.frame.update_idletasks()

root.mainloop()

這是autoScrollbar的源autoScrollbar ,因為其中包含了我在上面的源代碼中導入的內容,但我認為實際的問題不在這里。

# Adapted from here: http://effbot.org/zone/tkinter-autoscrollbar.htm

from Tkinter import Scrollbar

class AutoScrollbar(Scrollbar):
    '''
    A scrollbar that hides itself if it's not needed. 
    Only works if you use the grid geometry manager.
    '''
    def set(self, lo, hi):
        if float(lo) <= 0.0 and float(hi) >= 1.0:
            self.grid_remove()
        else:
            self.grid()
        Scrollbar.set(self, lo, hi)

    def pack(self, *args, **kwargs):
        raise TclError('Cannot use pack with this widget.')

    def place(self, *args, **kwargs):
        raise TclError('Cannot use pack with this widget.')

當畫布仍為空時,您正在調用canvas.config(scrollregion = canvas.bbox('all')) ,從而有效地使scrollregion (0, 0, 1, 1) 0,0,1,1 (0, 0, 1, 1)

您應該等待定義滾動區域,直到框架中有小部件為止。 為此,您應該在AutoScrollable類self.canvas canvas重命名為self.canvas並調用

autoScrollable.canvas.config(scrollregion = autoScrollable.canvas.bbox('all'))

之后

autoScrollable.frame.update_idletasks()

您還可以將<Configure>事件綁定到autoScrollable.frame ,該事件將調用update_idletasks()並更新scrollregion 這樣,您不必擔心自己再調用它,因為只要更改Frame的大小,它們就會更新。

    self.frame.bind('<Configure>', self.frame_changed)

def frame_changed(self, event):
    self.frame.update_idletasks()
    self.canvas.config(scrollregion = self.canvas.bbox('all'))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM