简体   繁体   中英

TKinter: Scrollable Canvas, Expandable Widgets, and Pack

I am creating a table using Labels laid out as a grid within a Frame. I'd like to embed this Frame in a scrollable canvas, and I'd like the Labels to expand to fill the horizontal space while maintaining vertical scrolling capability. To see what I am trying to do, here is my code:

class ScrollableTable(Frame):
def __init__(self, parent, rows=4, columns=5):
    self.rows = rows
    self.columns = columns

    Frame.__init__(self, parent, borderwidth=0, background='green')
    self.canvas = Canvas(self, borderwidth=0)
    self.frame = Frame(self.canvas, borderwidth=0, background='black')  
    self.vsb = Scrollbar(parent, orient=VERTICAL, command=self.canvas.yview)    
    self.canvas.configure(yscrollcommand=self.vsb.set)            
    self.canvas.pack(side=LEFT, fill=X, expand=TRUE)      
    # This is where I fix the height I want this window to take up         
    self.canvas.configure(yscrollcommand=self.vsb.set, width=720, height=80)
    self.height = self.canvas.winfo_reqheight()
    self.width = self.canvas.winfo_reqwidth()        

    self._widgets = []        
    for row in range(rows):
        current_row = []
        for column in range(columns):
            label = Label(self.frame, text="N/A", 
                             borderwidth=0, width=5, anchor=W, justify=LEFT)
            label.grid(row=row, column=column, sticky='NESW', padx=0.5, pady=0.5)
            current_row.append(label)
        self._widgets.append(current_row)

    self.canvas.create_window((0,0), window=self.frame, anchor='w', tags=self.frame)
    self.frame.bind("<Configure>", self.OnFrameConfigure)
    self.canvas.bind("<Configure>", self.onResize)  
    #self.frame.pack(side=LEFT, fill=X, expand=True)  
    self.vsb.pack(side=RIGHT, fill=Y, expand=True)    

In the above code, the 2nd to last line is commented. When it is commented out, I get a table that doesn't expand to fill the space, but the scrollbar works. However, if I uncomment that lines and use the frame.pack approach, the table fills the horizontal space, but I lose scrolling capability. I'm having trouble wrapping my head around why I'm losing the ability to scroll - any pointers?

You need to not call pack on the frame, and because of that you'll need to manage the width of the frame manually. Typically you do this by binding to the <Configure> event on the canvas. In the bound function, get the width of the canvas, and then use the itemconfigure method to set the width of the window object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM