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!
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.
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()