'How to change the width of a tkk Scrollbar in a custom style?

When defining a custom style for ttk Scrollbar, I'm stuck how can I change the width of the scrollbar. I have noticed that the width (thickness) shrinks when I copy elements TScrollbar.grip from another theme but when I have looked for element options style.element_options('My.Vertical.TScrollbar.grip') I get "".

from tkinter import *
from tkinter import ttk

root = Tk()
style = ttk.Style()

# import elements from the 'clam' engine.
style.element_create("My.Vertical.TScrollbar.trough", "from", "clam")
style.element_create("My.Vertical.TScrollbar.thumb", "from", "clam")
style.element_create("My.Vertical.TScrollbar.grip", "from", "clam")

style.layout("My.Vertical.TScrollbar",
   [('My.Vertical.TScrollbar.trough', {'children':
       [('My.Vertical.TScrollbar.thumb', {'unit': '1', 'children':
            [('My.Vertical.TScrollbar.grip', {'sticky': ''})],
       'sticky': 'nswe'})],
   'sticky': 'ns'})])


style.configure("My.Vertical.TScrollbar", gripcount=0, background="#464647",troughcolor='#252526', borderwidth=2,
bordercolor='#252526', lightcolor='#252526', darkcolor='#252526')

container = ttk.Frame(root)
canvas = Canvas(container)
scrollbar = ttk.Scrollbar(container, orient="vertical", command=canvas.yview, style="My.Vertical.TScrollbar")
scrollable_frame = ttk.Frame(canvas)
 
scrollable_frame.bind(
    "<Configure>",
    lambda e: canvas.configure(
        scrollregion=canvas.bbox("all")
    )
)

canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)

for i in range(50):
    ttk.Label(scrollable_frame, text="Sample scrolling label").pack()

container.pack()
canvas.pack(side="left", fill="both")
scrollbar.pack(side="right", fill="y")

root.mainloop()


Solution 1:[1]

After making a few cosmetic changes to your code to make it more readable, I was able to change the scrollbar's width by specify an arrowsize= option when configuring the overall style. This is done in the style.configure() call and is shown below on the line with the comment # <----- ADDED THIS.

I got the idea to use this option based on some documentation I found on the ttk.Scrollbar widget which states that while it doesn't support a width option like a tkinter.Scrollbar does, you can instead:

Configure this option using a style. You may find that configuring arrowsize is a better choice; in some themes, increasing the width may not increase the size of the arrowheads.

I first tried specifying a width, but it had no affect.

from tkinter import *
from tkinter import ttk

root = Tk()
style = ttk.Style()

# import elements from the 'clam' engine.
style.element_create("My.Vertical.TScrollbar.trough", "from", "clam")
style.element_create("My.Vertical.TScrollbar.thumb", "from", "clam")
style.element_create("My.Vertical.TScrollbar.grip", "from", "clam")

style.layout("My.Vertical.TScrollbar",
   [('My.Vertical.TScrollbar.trough',
     {'children': [('My.Vertical.TScrollbar.thumb',
                    {'unit': '1',
                     'children':
                        [('My.Vertical.TScrollbar.grip', {'sticky': ''})],
                     'sticky': 'nswe'})
                  ],
      'sticky': 'ns'})])

style.configure("My.Vertical.TScrollbar", gripcount=0, background="#b0b0b0",
                troughcolor='#252526', borderwidth=2, bordercolor='#252526',
                lightcolor='#252526', darkcolor='#252526',
                arrowsize=40)  # <----- ADDED THIS.

container = ttk.Frame(root)
canvas = Canvas(container)
scrollbar = ttk.Scrollbar(container, orient="vertical", command=canvas.yview,
                          style="My.Vertical.TScrollbar")
scrollable_frame = ttk.Frame(canvas)

scrollable_frame.bind("<Configure>",
                      lambda e: canvas.configure(scrollregion=canvas.bbox("all")))

canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)

for i in range(50):
    ttk.Label(scrollable_frame, text=f"Sample scrolling label {i}").pack()

container.pack()
canvas.pack(side="left", fill="both")
scrollbar.pack(side="right", fill="y")

root.mainloop()

The result looked like this:

screenshot show wide vertial scrollbar

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1