Skip to content

Commit 8576976

Browse files
committed
Add files
1 parent c3db409 commit 8576976

File tree

149 files changed

+1442
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+1442
-2
lines changed

README.md

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,81 @@
1-
# Forest-ttk-theme
2-
The Forest theme is a beautiful and modern ttk theme inspired by Excel.
1+
# Forest theme for ttk
2+
3+
4+
## How to use
5+
### Python / tkinter
6+
To use the theme just import the **forest-light.tcl**, or the **forest-dark.tcl** file, and call the `theme_use` method to set the theme:
7+
```python
8+
# Import the tcl file
9+
root.tk.call('source', 'forest-light.tcl / forest-dark.tcl')
10+
11+
# Set the theme with the theme_use method
12+
ttk.Style().theme_use('forest-light / forest-dark')
13+
```
14+
15+
### Tcl / tk
16+
To use the theme just import the **forest-light.tcl**, or the **forest-dark.tcl** file, and call the `theme use` method to set the theme:
17+
```tcl
18+
# Import the tcl file
19+
source "forest-light.tcl / forest-dark.tcl"
20+
21+
# Set theme using the theme use method
22+
ttk::style theme use forest-light / forest-dark
23+
```
24+
25+
## New style elements
26+
The Forest theme similar to my [Azure theme](https://github.com/rdbende/Azure-ttk-theme) has some **new** widget styles, such as an accent button, toggle switch, toggle button and card. You can apply these with the style option.
27+
28+
If you need a highlighted button, use `Accent.TButton`:
29+
```python
30+
button = ttk.Button(root, text='Accent button', style='Accent.TButton', command=callback)
31+
```
32+
33+
To create a toggle button you need a checkbutton, to which you can apply the `ToggleButton` style:
34+
```python
35+
togglebutton = ttk.Checkbutton(root, text='Toggle button', style='ToggleButton', variable=var)
36+
```
37+
38+
The use of switches is becoming more common these days, so this theme has a `Switch` style, that can be applied to checkbuttons:
39+
```python
40+
switch = ttk.Checkbutton(root, text='Switch', style='Switch', variable=var)
41+
```
42+
43+
If you only want a border around your widgets, not an entire LabelFrame then apply the `Card` style to a Frame:
44+
```python
45+
card = ttk.Frame(root, style='Card', padding=(5, 6, 7, 8))
46+
```
47+
48+
## A short example
49+
for Python...
50+
```python
51+
import tkinter as tk
52+
from tkinter import ttk
53+
54+
root = tk.Tk()
55+
56+
# Import the tcl file
57+
root.tk.call('source', 'forest-dark.tcl')
58+
59+
# Set the theme with the theme_use method
60+
ttk.Style().theme_use('forest-dark')
61+
62+
# A themed (ttk) button
63+
button = ttk.Button(root, text="I'm a themed button")
64+
button.pack(pady=20)
65+
66+
root.mainloop()
67+
```
68+
...and for Tcl
69+
```tcl
70+
package require Tk 8.6
71+
72+
# Import the tcl file
73+
source "forest-dark.tcl"
74+
75+
# Set theme using the theme use method
76+
ttk::style theme use forest-dark
77+
78+
# A themed (ttk) button
79+
ttk::button .button -text "I'm a themed button"
80+
pack .button -pady 20
81+
```

example.py

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
"""
2+
Example script for testing the Forest theme
3+
4+
Author: rdbende
5+
License: MIT license
6+
Source: https://github.com/rdbende/ttk-widget-factory
7+
"""
8+
9+
10+
import tkinter as tk
11+
from tkinter import ttk
12+
13+
root = tk.Tk()
14+
root.title("Forest")
15+
root.option_add("*tearOff", False) # This is always a good idea
16+
17+
# Make the app responsive
18+
root.columnconfigure(index=0, weight=1)
19+
root.columnconfigure(index=1, weight=1)
20+
root.columnconfigure(index=2, weight=1)
21+
root.rowconfigure(index=0, weight=1)
22+
root.rowconfigure(index=1, weight=1)
23+
root.rowconfigure(index=2, weight=1)
24+
25+
# Create a style
26+
style = ttk.Style(root)
27+
28+
# Import the tcl file
29+
root.tk.call("source", "forest-dark.tcl")
30+
31+
# Set the theme with the theme_use method
32+
style.theme_use("forest-dark")
33+
34+
# Create lists for the Comboboxes
35+
option_menu_list = ["", "OptionMenu", "Option 1", "Option 2"]
36+
combo_list = ["Combobox", "Editable item 1", "Editable item 2"]
37+
readonly_combo_list = ["Readonly combobox", "Item 1", "Item 2"]
38+
39+
# Create control variables
40+
a = tk.BooleanVar()
41+
b = tk.BooleanVar(value=True)
42+
c = tk.BooleanVar()
43+
d = tk.IntVar(value=2)
44+
e = tk.StringVar(value=option_menu_list[1])
45+
f = tk.BooleanVar()
46+
g = tk.DoubleVar(value=75.0)
47+
h = tk.BooleanVar()
48+
49+
# Create a Frame for the Checkbuttons
50+
check_frame = ttk.LabelFrame(root, text="Checkbuttons", padding=(20, 10))
51+
check_frame.grid(row=0, column=0, padx=(20, 10), pady=(20, 10), sticky="nsew")
52+
53+
# Checkbuttons
54+
check_1 = ttk.Checkbutton(check_frame, text="Unchecked", variable=a)
55+
check_1.grid(row=0, column=0, padx=5, pady=10, sticky="nsew")
56+
check_2 = ttk.Checkbutton(check_frame, text="Checked", variable=b)
57+
check_2.grid(row=1, column=0, padx=5, pady=10, sticky="nsew")
58+
check_3 = ttk.Checkbutton(check_frame, text="Third state", variable=c)
59+
check_3.state(["alternate"])
60+
check_3.grid(row=2, column=0, padx=5, pady=10, sticky="nsew")
61+
check_4 = ttk.Checkbutton(check_frame, text="Disabled", state="disabled")
62+
check_4.state(["disabled !alternate"])
63+
check_4.grid(row=3, column=0, padx=5, pady=10, sticky="nsew")
64+
65+
# Separator
66+
separator = ttk.Separator(root)
67+
separator.grid(row=1, column=0, padx=(20, 10), pady=10, sticky="ew")
68+
69+
# Create a Frame for the Radiobuttons
70+
radio_frame = ttk.LabelFrame(root, text="Radiobuttons", padding=(20, 10))
71+
radio_frame.grid(row=2, column=0, padx=(20, 10), pady=10, sticky="nsew")
72+
73+
# Radiobuttons
74+
radio_1 = ttk.Radiobutton(radio_frame, text="Deselected", variable=d, value=1)
75+
radio_1.grid(row=0, column=0, padx=5, pady=10, sticky="nsew")
76+
radio_2 = ttk.Radiobutton(radio_frame, text="Selected", variable=d, value=2)
77+
radio_2.grid(row=1, column=0, padx=5, pady=10, sticky="nsew")
78+
radio_3 = ttk.Radiobutton(radio_frame, text="Mixed")
79+
radio_3.state(["alternate"])
80+
radio_3.grid(row=2, column=0, padx=5, pady=10, sticky="nsew")
81+
radio_4 = ttk.Radiobutton(radio_frame, text="Disabled", state="disabled")
82+
radio_4.grid(row=3, column=0, padx=5, pady=10, sticky="nsew")
83+
84+
# Create a Frame for input widgets
85+
widgets_frame = ttk.Frame(root, padding=(0, 0, 0, 10))
86+
widgets_frame.grid(row=0, column=1, padx=10, pady=(30, 10), sticky="nsew", rowspan=3)
87+
widgets_frame.columnconfigure(index=0, weight=1)
88+
89+
# Entry
90+
entry = ttk.Entry(widgets_frame)
91+
entry.insert(0, "Entry")
92+
entry.grid(row=0, column=0, padx=5, pady=(0, 10), sticky="ew")
93+
94+
# Spinbox
95+
spinbox = ttk.Spinbox(widgets_frame, from_=0, to=100, increment=0.1)
96+
spinbox.insert(0, "Spinbox")
97+
spinbox.grid(row=1, column=0, padx=5, pady=10, sticky="ew")
98+
99+
# Combobox
100+
combobox = ttk.Combobox(widgets_frame, values=combo_list)
101+
combobox.current(0)
102+
combobox.grid(row=2, column=0, padx=5, pady=10, sticky="ew")
103+
104+
# Read-only combobox
105+
readonly_combo = ttk.Combobox(widgets_frame, state="readonly", values=readonly_combo_list)
106+
readonly_combo.current(0)
107+
readonly_combo.grid(row=3, column=0, padx=5, pady=10, sticky="ew")
108+
109+
# Menu for the Menubutton
110+
menu = tk.Menu(widgets_frame)
111+
menu.add_command(label="Menu item 1")
112+
menu.add_command(label="Menu item 2")
113+
menu.add_separator()
114+
menu.add_command(label="Menu item 3")
115+
menu.add_command(label="Menu item 4")
116+
117+
# Menubutton
118+
menubutton = ttk.Menubutton(widgets_frame, text="Menubutton", menu=menu, direction="below")
119+
menubutton.grid(row=4, column=0, padx=5, pady=10, sticky="nsew")
120+
121+
# OptionMenu
122+
optionmenu = ttk.OptionMenu(widgets_frame, e, *option_menu_list)
123+
optionmenu.grid(row=5, column=0, padx=5, pady=10, sticky="nsew")
124+
125+
# Button
126+
button = ttk.Button(widgets_frame, text="Button")
127+
button.grid(row=6, column=0, padx=5, pady=10, sticky="nsew")
128+
129+
# Accentbutton
130+
accentbutton = ttk.Button(widgets_frame, text="Accentbutton", style="Accent.TButton")
131+
accentbutton.grid(row=7, column=0, padx=5, pady=10, sticky="nsew")
132+
133+
# Togglebutton
134+
button = ttk.Checkbutton(widgets_frame, text="Togglebutton", style="ToggleButton")
135+
button.grid(row=8, column=0, padx=5, pady=10, sticky="nsew")
136+
137+
# Switch
138+
switch = ttk.Checkbutton(widgets_frame, text="Switch", style="Switch")
139+
switch.grid(row=9, column=0, padx=5, pady=10, sticky="nsew")
140+
141+
# Panedwindow
142+
paned = ttk.PanedWindow(root)
143+
paned.grid(row=0, column=2, pady=(25, 5), sticky="nsew", rowspan=3)
144+
145+
# Pane #1
146+
pane_1 = ttk.Frame(paned)
147+
paned.add(pane_1, weight=1)
148+
149+
# Create a Frame for the Treeview
150+
treeFrame = ttk.Frame(pane_1)
151+
treeFrame.pack(expand=True, fill="both", padx=5, pady=5)
152+
153+
# Scrollbar
154+
treeScroll = ttk.Scrollbar(treeFrame)
155+
treeScroll.pack(side="right", fill="y")
156+
157+
# Treeview
158+
treeview = ttk.Treeview(treeFrame, selectmode="extended", yscrollcommand=treeScroll.set, columns=(1, 2), height=12)
159+
treeview.pack(expand=True, fill="both")
160+
treeScroll.config(command=treeview.yview)
161+
162+
# Treeview columns
163+
treeview.column("#0", width=120)
164+
treeview.column(1, anchor="w", width=120)
165+
treeview.column(2, anchor="w", width=120)
166+
167+
# Treeview headings
168+
treeview.heading("#0", text="Column 1", anchor="center")
169+
treeview.heading(1, text="Column 2", anchor="center")
170+
treeview.heading(2, text="Column 3", anchor="center")
171+
172+
# Define treeview data
173+
treeview_data = [
174+
("", "end", 1, "Parent", ("Item 1", "Value 1")),
175+
(1, "end", 2, "Child", ("Subitem 1.1", "Value 1.1")),
176+
(1, "end", 3, "Child", ("Subitem 1.2", "Value 1.2")),
177+
(1, "end", 4, "Child", ("Subitem 1.3", "Value 1.3")),
178+
(1, "end", 5, "Child", ("Subitem 1.4", "Value 1.4")),
179+
("", "end", 6, "Parent", ("Item 2", "Value 2")),
180+
(6, "end", 7, "Child", ("Subitem 2.1", "Value 2.1")),
181+
(6, "end", 8, "Sub-parent", ("Subitem 2.2", "Value 2.2")),
182+
(8, "end", 9, "Child", ("Subitem 2.2.1", "Value 2.2.1")),
183+
(8, "end", 10, "Child", ("Subitem 2.2.2", "Value 2.2.2")),
184+
(8, "end", 11, "Child", ("Subitem 2.2.3", "Value 2.2.3")),
185+
(6, "end", 12, "Child", ("Subitem 2.3", "Value 2.3")),
186+
(6, "end", 13, "Child", ("Subitem 2.4", "Value 2.4")),
187+
("", "end", 14, "Parent", ("Item 3", "Value 3")),
188+
(14, "end", 15, "Child", ("Subitem 3.1", "Value 3.1")),
189+
(14, "end", 16, "Child", ("Subitem 3.2", "Value 3.2")),
190+
(14, "end", 17, "Child", ("Subitem 3.3", "Value 3.3")),
191+
(14, "end", 18, "Child", ("Subitem 3.4", "Value 3.4")),
192+
("", "end", 19, "Parent", ("Item 4", "Value 4")),
193+
(19, "end", 20, "Child", ("Subitem 4.1", "Value 4.1")),
194+
(19, "end", 21, "Sub-parent", ("Subitem 4.2", "Value 4.2")),
195+
(21, "end", 22, "Child", ("Subitem 4.2.1", "Value 4.2.1")),
196+
(21, "end", 23, "Child", ("Subitem 4.2.2", "Value 4.2.2")),
197+
(21, "end", 24, "Child", ("Subitem 4.2.3", "Value 4.2.3")),
198+
(19, "end", 25, "Child", ("Subitem 4.3", "Value 4.3"))
199+
]
200+
201+
# Insert treeview data
202+
for item in treeview_data:
203+
treeview.insert(parent=item[0], index=item[1], iid=item[2], text=item[3], values=item[4])
204+
if item[0] == "" or item[2] == 8 or item[2] == 21:
205+
treeview.item(item[2], open=True) # Open parents
206+
207+
# Select and scroll
208+
treeview.selection_set(9)
209+
treeview.see(7)
210+
211+
# Pane #2
212+
pane_2 = ttk.Frame(paned)
213+
paned.add(pane_2, weight=3)
214+
215+
# Notebook
216+
notebook = ttk.Notebook(pane_2)
217+
218+
# Tab #1
219+
tab_1 = ttk.Frame(notebook)
220+
tab_1.columnconfigure(index=0, weight=1)
221+
tab_1.columnconfigure(index=1, weight=1)
222+
tab_1.rowconfigure(index=0, weight=1)
223+
tab_1.rowconfigure(index=1, weight=1)
224+
notebook.add(tab_1, text="Tab 1")
225+
226+
# Scale
227+
scale = ttk.Scale(tab_1, from_=100, to=0, variable=g, command=lambda event: g.set(scale.get()))
228+
scale.grid(row=0, column=0, padx=(20, 10), pady=(20, 0), sticky="ew")
229+
230+
# Progressbar
231+
progress = ttk.Progressbar(tab_1, value=0, variable=g, mode="determinate")
232+
progress.grid(row=0, column=1, padx=(10, 20), pady=(20, 0), sticky="ew")
233+
234+
# Label
235+
label = ttk.Label(tab_1, text="Forest ttk theme", justify="center")
236+
label.grid(row=1, column=0, pady=10, columnspan=2)
237+
238+
# Tab #2
239+
tab_2 = ttk.Frame(notebook)
240+
notebook.add(tab_2, text="Tab 2")
241+
242+
# Tab #3
243+
tab_3 = ttk.Frame(notebook)
244+
notebook.add(tab_3, text="Tab 3")
245+
246+
notebook.pack(expand=True, fill="both", padx=5, pady=5)
247+
248+
# Sizegrip
249+
sizegrip = ttk.Sizegrip(root)
250+
sizegrip.grid(row=100, column=100, padx=(0, 5), pady=(0, 5))
251+
252+
# Center the window, and set minsize
253+
root.update()
254+
root.minsize(root.winfo_width(), root.winfo_height())
255+
x_cordinate = int((root.winfo_screenwidth()/2) - (root.winfo_width()/2))
256+
y_cordinate = int((root.winfo_screenheight()/2) - (root.winfo_height()/2))
257+
root.geometry("+{}+{}".format(x_cordinate, y_cordinate))
258+
259+
# Start the main loop
260+
root.mainloop()

0 commit comments

Comments
 (0)