Home > Back-end >  Resize scroll for checkbox tkinter
Resize scroll for checkbox tkinter

Time:01-18

After several tests and help received, I managed to get the code for a scroll with several checkboxes inside. My current problem is that the scroll is much larger than the space it needs and in general I can't change its size to my liking. This is my code:

import tkinter as tk
class CheckboxList(tk.Frame):
    def __init__(self, master=None, **kw):
        super().__init__(master, **kw)
        self.checkbuttons = []
        self.vars = []
        self.canvas = tk.Canvas(self, bg='white', bd=0, highlightthickness=0)
        self.yscroll = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.frame = tk.Frame(self.canvas)
        self.canvas.create_window((0, 0), window=self.frame, anchor='nw')
        self.canvas.configure(yscrollcommand=self.yscroll.set)
        self.canvas.grid(row=0,column=0, sticky='nsew')
        self.yscroll.grid(row=0, column=1, sticky='nse')
        for i in range(20):
            var = tk.IntVar(value=0)
            cb = tk.Checkbutton(self.frame, text=f"checkbutton #{i}", variable=var, onvalue=1, offvalue=0)
            cb.grid(row=i, column=0, sticky='w')
            self.checkbuttons.append(cb)
            self.vars.append(var)
        self.frame.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox("all"))
        
        self.canvas.bind_all("<MouseWheel>", self._on_mousewheel)
        
    def _on_mousewheel(self, event):
        self.canvas.yview_scroll(int(-1*(event.delta/120)), "units")

root = tk.Tk()
cl = CheckboxList(root, width=20, height=10)
cl.grid(row=0,column=0,sticky='nsew')
root.mainloop()

I have made several tests by changing the values of "grid" but I can not. I wish I could have more control over the size. As you can see from the image, there is a lot of white space left and I would like to be able to change the overall height as well enter image description here

CodePudding user response:

Add width in line 8.

Change this:

self.canvas = tk.Canvas(self, bg='white', bd=0, highlightthickness=0)

to:

self.canvas = tk.Canvas(self, bg='white', bd=0,width=115, highlightthickness=0)

Screenshot:

enter image description here

CodePudding user response:

You can set the width of self.canvas same as self.frame whenever self.frame is resized via callback of event <Configure> on self.frame. Note also that you need to update scrollregion of the canvas when the size of self.frame is changed, not self.canvas.

        ...
        self.frame = tk.Frame(self.canvas)
        self.frame.bind("<Configure>", lambda e: self.canvas.config(width=e.width, scrollregion=self.canvas.bbox("all")))
        ...
        # scrollregion does not change when canvas is resized, so below binding is useless
        #self.canvas.config(scrollregion=self.canvas.bbox("all"))
        ...
  • Related