Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing the appearance of a Scrollbar in tkinter (using ttk styles)

I was wondering if you could help me with a style options issue in ttk. I've managed to change most of the basic ttk widgets to the style of my preference. I'm only stuck at changing the style of a scrollbar. I've searched for hours looking for an answer, unfortunately to no avail.

Here's a sample code using the scrollbar style option:

import tkinter as tk                 
from tkinter import ttk

class Gui:
    def __init__(self,mainframe):

        #set the style
        style = ttk.Style()
        style.configure('Horizontal.TScrollbar',background = "blue" )   

        #Create a mainframe
        self.mainframe = mainframe
        self.mainframe.title("example")


        #creating scrollbar frame
        scrl_attr_frame = ttk.Frame(self.mainframe)                            
        scrl_attr_frame.grid(column=0,row=5,sticky="ns")                                           
        scrl_attr_frame.rowconfigure(0, weight=1)                                                   
        attr_canvas = tk.Canvas(scrl_attr_frame)                                                   
        h_scroll = ttk.Scrollbar(scrl_attr_frame,orient="horizontal", command=attr_canvas.xview)
        attr_canvas.configure(xscrollcommand=h_scroll.set)                                       
        attr_canvas.grid(column=0,row=0,sticky="ns")                                                                            
        h_scroll.grid(column=0, row=1,sticky="we") 
        attr_frame = ttk.Frame(attr_canvas)                                                        
        attr_frame.grid(column=0,row=0,sticky="ns")                                                 
        attr_canvas.create_window((0,0),window=attr_frame, anchor='nw')
        attr_frame.bind("<Configure>",lambda event, canvas=attr_canvas : canvas.configure(scrollregion=canvas.bbox("all"),width=200,height=200,takefocus=False,highlightthickness=0))#attribute_frame.winfo_height()/20,highlightthickness=0))

        #setup treeview widget
        tree_columns = ("c1", "c2", "c3")

        self.tree = ttk.Treeview(attr_frame,columns=tree_columns, show="headings",takefocus=False)
        self.tree.grid(column=0, row=0, sticky='nsew')

        for head in tree_columns:
            self.tree.heading(head,text=head,anchor="w")


root = tk.Tk()
myapp = Gui(root)
root.mainloop()

I also tried several combinations including;

style.configure('TScrollbar',background='blue') 

#and
style.configure('CustomScroll.Horizontal.TScrollbar',background='blue')

#in combination with
h_scroll = ttk.Scrollbar(scrl_attr_frame,orient="horizontal", command=attr_canvas.xview)
h_scroll['style'] = "CustomScroll.Horizontal.TScrollbar" 

Many thanks for your help!

like image 268
StephanL Avatar asked Feb 06 '15 22:02

StephanL


People also ask

What is the use of TTK in tkinter?

The tkinter. ttk module provides access to the Tk themed widget set, introduced in Tk 8.5. It provides additional benefits including anti-aliased font rendering under X11 and window transparency (requiring a composition window manager on X11). The basic idea for tkinter.

What is the difference between Tk and TTK in Python?

Tkinter widgets are used to add Buttons, Labels, Text, ScrollBar, etc., however, tkinter. ttk supports a variety of widgets as compared to tkinter widgets. Tkinter. ttk doesn't support Place, Pack() and Grid(), thus it is recommended to use tkinter widget with ttk.

Can we add scrollbar to label in tkinter?

The Scrollbar widget in tkinter is one of the useful widgets that is used to pack the container elements and their contents with a scrollbar. With Scrollbars, we can view large sets of data very efficiently. Generally, Tkinter allows to add vertical and horizontal scrollbar in the application.

How do you scroll frame in tkinter?

The horizontal scrollbar is useful to view the text from left to right. The vertical scrollbar is useful to scroll the text from top to bottom. On attaching the scrollbar to a widget like text box, list box, etc we then have to add a command xview for horizontal scrollbar and yview for the vertical scrollbar.


1 Answers

It looks like you just want to change the trough for a horizontal scrollbar under the Windows theme. The ttk widgets are constructed from a set of elements provided by a styling engine and combined using the declared layout. Under Windows the styling engine is the Windows Visual Styles API which means the programmer doesn't have any control over the colours or images used to draw most of the common elements. The button background, scrollbar trough and buttons and the thumb and even the grip drawn inside the scrollbar thumb are all provided by Windows.

It is possible to take control of this for application customization but at a cost of making your application no longer look standard on the given platform. To do this you have to provide your own UI elements and define new widget layouts. Ultimately this can turn into defining your own theme. The tcl scripts in the ttk library provide good examples to follow and there are even some complete (if old) themes using bitmaps to declare image based theme elements in the original version of ttk which was called 'tile'.

In this specific example to get a Windows horizontal scrollbar with a custom coloured background we need to redefine the layout to use the scrollbar trough from the Tk drawn elements. The elements used in the 'default' theme can be copied in and are defined using style configuration parameters and are then drawn by Tk itself and not passed off to a third party engine. The following code generates a scrollbar like this which uses the standard buttons and thumb provided by the vsapi styling engine but replaces the trough. This imported trough understands the troughcolor style configuration option and so we can define a colour to use now. All scrollbars using this style will use the same colour as the widget itself will not accept a troughcolor option. ie: you can't have one scrollbar be blue and another be red unless you define a new style for each new colour.

enter image description here

from tkinter import *
from tkinter.ttk import *

def main():
    app = Tk()
    style = Style()

    # import the 'trough' element from the 'default' engine.
    style.element_create("My.Horizontal.Scrollbar.trough", "from", "default")

    # Redefine the horizontal scrollbar layout to use the custom trough.
    # This one is appropriate for the 'vista' theme.
    style.layout("My.Horizontal.TScrollbar",
        [('My.Horizontal.Scrollbar.trough', {'children':
            [('Horizontal.Scrollbar.leftarrow', {'side': 'left', 'sticky': ''}),
             ('Horizontal.Scrollbar.rightarrow', {'side': 'right', 'sticky': ''}),
             ('Horizontal.Scrollbar.thumb', {'unit': '1', 'children':
                 [('Horizontal.Scrollbar.grip', {'sticky': ''})],
            'sticky': 'nswe'})],
        'sticky': 'we'})])
    # Copy original style configuration and add our new custom configuration option.
    style.configure("My.Horizontal.TScrollbar", *style.configure("Horizontal.TScrollbar"))
    style.configure("My.Horizontal.TScrollbar", troughcolor="red")

    # Create and show a widget using the custom style
    hs = Scrollbar(app, orient="horizontal", style="My.Horizontal.TScrollbar")
    hs.place(x=5, y=5, width=150)
    hs.set(0.2,0.3)

    app.mainloop()

if __name__ == '__main__':
    main()
like image 182
patthoyts Avatar answered Sep 20 '22 12:09

patthoyts