Combobox#
Let's see if we can pin the above on an example or two. First let us change the combobox on both our test themes to that used by radiance. On my computer with Windows 10 and python 3.6, the combobox from elegance aka green looks like
Show/Hide Code 06show_green_combo.py
import tkinter as tk
import tkinter.ttk as ttk
import ttkthemes as ts
root = tk.Tk()
s = ts.themed_style.ThemedStyle()
s.theme_use('green')
ttk.Combobox(root,values='green').pack() # 'elegance'
root.mainloop()
whereas radiance looks like
Show/Hide Code 06show_radiance_combo.py
import tkinter as tk
import tkinter.ttk as ttk
import ttkthemes as ts
root = tk.Tk()
s = ts.themed_style.ThemedStyle()
s.theme_use('radiance')
ttk.Combobox(root,values='radiance').pack()
root.mainloop()
Say we prefer the radiance combobox and want to run it in our green theme.
Compare the tcl files, radiance.tcl consists of the following
## Combobox.
#
ttk::style configure TCombobox -selectbackground
ttk::style element create Combobox.downarrow image \
[list $I(comboarrow-n) \
disabled $I(comboarrow-d) \
pressed $I(comboarrow-p) \
active $I(comboarrow-a) \
] \
-border 1 -sticky {}
ttk::style element create Combobox.field image \
[list $I(combo-n) \
{readonly disabled} $I(combo-rd) \
{readonly pressed} $I(combo-rp) \
{readonly focus} $I(combo-rf) \
readonly $I(combo-rn) \
] \
-border 4 -sticky ew
whereas green.tcl looks like
# Combobox
#
::ttk::style element create Combobox.field image \
[list $I(combo-active) \
{readonly} $I(button-active) \
{active} $I(combo-active) \
] -border {9 10 32 15} -padding {9 4 8 4} -sticky news
::ttk::style element create Combobox.downarrow image \
[list $I(stepper-down) disabled $I(stepper-down)] \
-sticky e -border {15 0 0 0}
In both cases the combobox uses element create for the components field and downarrow. Radiance has fewer images, which luckily do not have a name clash with any of the green image names. It seems that we should be able to replace the relevant script parts and copy all the radiance image files to the green image directory. When this is done we can test with one of our files such as 06theme_notebook.py, or 06combobox_text_theme.py.
Both scripts have a combobox with theme selector, our green theme should be in the dropdown list, go on select it.
This should look something like:-
which as you can see on my windows box is not quite the same as the radiance combobox, look at the position of the down arrow. Check green.tcl and see that there is no parent theme in the line:
::ttk::style theme create green -settings {
unlike radiance.tcl where we find
ttk::style theme create radiance -parent clam -settings {
since elegance (aka green) was probably created in Linux the normal theme would have been default. Using default as the parent theme the combobox is not altered enough - let's try the clam theme instead - ahh far better.
That wasn't too bad was it? Now for the orange theme, taken from orange.py .
"Combobox.field": {"element create":
("image", 'combo-n',
('readonly', 'active', 'combo-ra'),
('focus', 'active', 'combo-fa'),
('active', 'combo-a'), ('!readonly', 'focus', 'combo-f'),
('readonly', 'combo-r'),
{'border': [4, 6, 24, 15], 'padding': [4, 4, 5],
'sticky': 'news'}
)
},
"Combobox.downarrow": {"element create":
("image", 'arrow-d', {'sticky': 'e', 'border': [15, 0, 0, 0]})
},
We have to be careful not to overwrite orange combo- image files with our new
files imported from radiance, give them a new designation, say combor- so the
old files remain until all has been tested. Also we have to ensure that we have
the python corresponding to the tcl in radiance.tcl.
It's probably best to run a python test file such as 06widget_orange_test.py.
Show/Hide Code 06widget_orange_test.py
1'''
2Using theme_create to test the script for the orange standalone theme.
3When using theme_settings it gave an error message - not yet resolved.
4'''
5
6from tkinter.ttk import Style, Combobox
7from tkinter import Tk, PhotoImage
8
9root = Tk()
10style = Style()
11im0 = PhotoImage('combor-n', file='../images/combor-n.gif')
12im1 = PhotoImage('combor-rd',file='../images/combor-rd.gif')
13im2 = PhotoImage('combor-rp',file='../images/combor-rp.gif')
14im3 = PhotoImage('combor-rf',file='../images/combor-rf.gif')
15im4 = PhotoImage('combor-rn',file='../images/combor-rn.gif')
16im5 = PhotoImage('comboarrow-n',file='../images/comboarrow-n.gif')
17im6 = PhotoImage('comboarrow-p',file='../images/comboarrow-p.gif')
18im7 = PhotoImage('comboarrow-a',file='../images/comboarrow-a.gif')
19im8 = PhotoImage('comboarrow-d',file='../images/comboarrow-d.gif')
20
21# Try theme_settings, comment out theme_create uncomment theme_settings
22# also change theme_use
23style.theme_create('test', parent="clam", settings={
24#style.theme_settings("clam", {
25 "TCombobox": {
26 "configure": {"selectbackground": "#657a9e"}}, # 'light blue'
27 "Combobox.field": {"element create":
28 ("image", 'combor-n',
29 ('readonly', 'disabled', 'combor-rd'),
30 ('readonly', 'pressed', 'combor-rp'),
31 ('readonly', 'focus', 'combor-rf'),
32 ('readonly', 'combor-rn'),
33 {'sticky': 'ew', 'border': [4]}
34 )
35 },
36 "Combobox.downarrow": {"element create":
37 ("image", 'comboarrow-n',
38 ('disabled','comboarrow-d'),
39 ('pressed','comboarrow-p'),
40 ('active','comboarrow-a'),
41 {'sticky': '','border': [1]}
42 )
43 }
44})
45
46style.theme_use('test') # change to style.theme_use('clam') if using theme_settings
47combo = Combobox(values=['apple', 'banana', 'orange']).pack()
48root.mainloop()
Copy the necessary radiance image files to our orange images directory,
renaming as necessary. When running theme_create you can experiment
having the parent directory as default instead of clam - the results should
be similar to those given in the green.tcl test. The resulting python script
within theme_create (lines25-43) can be used to overwrite the combobox part of orange.py.
Remember to change any combor to combo. We can test whether orange.py is correct using 06combo_orange.py.
Show/Hide Code 06combo_orange.py
import tkinter as tk
from tkinter import ttk
import orange_theme # when using theme the style is not required
values = ['car', 'house', 'computer']
root = tk.Tk()
labels = dict((value, ttk.Label(root, text=value)) for value in values)
try:
orange_theme.install('../images/orange')
except Exception:
import warnings
warnings.warn("orange theme being used without images")
def handler(event):
current = combobox.current()
if current != -1:
for label in labels.values():
label.config(relief='flat')
value = values[current]
print(value)
label = labels[value]
label.config(relief='raised')
combobox = ttk.Combobox(root, values=values)
combobox.bind('<<ComboboxSelected>>', handler)
combobox.pack()
for value in labels:
labels[value].pack()
root.mainloop()
Tip
If the down arrow of the orange combobox is misplaced, as we saw above for the green theme, find the theme_create line in the orange theme and change "default" to "clam" which sorts out combobox but may have side effects on other widgets.
When working with radiance note how often the widgets have their images added by using "element create" - there are not so many widgets that require a layout and mapping. This bodes well for any future designs we may have since this is a relatively simple construct.