-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pythonic theme creation #68
Comments
Hi @formateli ! The themes are indeed created using Tcl-code. There are three reasons for this:
If you find that the performance would be better using Python code rather than Tcl code, please let me know. I'd love to see some numbers on it. If your application is rendering slowly, make sure to set |
@formateli , @RedFantom, yes, you can develop themes using python... though, consulting the ttkthemes tcl code will be crucial to understanding and learning what you need to do in python, as it's not documented anywhere well. Rebuilding the arc theme in python, and consulting the tcl/tk man pages is how I learned to do this. Here's a simple example of creating a new theme with a single custom widget - a modern looking radiobutton. from PIL import ImageDraw, Image, ImageTk
from tkinter import ttk
style = ttk.Style()
# radio off image
radio_off = Image.new('RGBA', (134, 134))
draw = ImageDraw.Draw(radio_off)
draw.ellipse([2, 2, 132, 132], outline="#adb5bd", width=3, fill="#f8f9fa")
radio_off_img = ImageTk.PhotoImage(radio_off.resize((14, 14), Image.LANCZOS))
# radio on image
radio_on = Image.new('RGBA', (134, 134))
draw = ImageDraw.Draw(radio_on)
draw.ellipse([2, 2, 132, 132], outline="#4582ec", width=12, fill="#4582ec")
draw.ellipse([40, 40, 94, 94], fill="#ffffff")
radio_on_img = ImageTk.PhotoImage(radio_on.resize((14, 14), Image.LANCZOS))
# radio disabled image
radio_disabled = Image.new('RGBA', (134, 134))
draw = ImageDraw.Draw(radio_disabled)
draw.ellipse([2, 2, 132, 132], outline="#c5c7c7", width=3, fill="#f8f9fa")
draw.ellipse([40, 40, 94, 94], fill="#f8f9fa")
radio_disabled_img = ImageTk.PhotoImage(radio_disabled.resize((14, 14), Image.LANCZOS))
# create theme settings
theme_settings = {
'Radiobutton.indicator': {
'element create': ('image', radio_on_img,
('disabled', radio_disabled_img),
('!selected', radio_off_img),
{'width': 28, 'border': 4, 'sticky': 'w'})},
'TRadiobutton': {
'layout': [
('Radiobutton.padding', {'children': [
('primary.Radiobutton.indicator', {'side': 'left', 'sticky': ''}),
('Radiobutton.focus', {'children': [
('Radiobutton.label', {'sticky': 'nswe'})], 'side': 'left', 'sticky': ''})],
'sticky': 'nswe'})],
'configure': {
'background': "#ffffff",
'foreground': "#343a40",
'focuscolor': ''},
'map': {
'background': [
('active', '#ffffff')],
'foreground': [
('disabled', "#c5c7c7"),
('active !disabled', "#4582ec")]}}}
# create and apply custom theme
style.theme_create('myawesometheme', 'clam', theme_settings)
style.theme_use('myawesometheme')
# set the background to white (too lazy to create a frame)
style.master.configure(background="#ffffff")
# add the new widgets that I created
ttk.Radiobutton(text='option 1 - selected', value=1).pack(fill='x', padx=20, pady=(20, 2))
ttk.Radiobutton(text='option 2', value=2).pack(fill='x', padx=20, pady=2)
ttk.Radiobutton(text='option 3', value=3).pack(fill='x', padx=20, pady=2)
ttk.Radiobutton(text='option 4 - disabled', value=4, state='disabled').pack(fill='x', padx=20, pady=(2, 20))
style.master.mainloop() In the example above I used a dictionary of settings. However, you can just as well do it with the If you're interested in seeing what can be done, I'm developing a python package called ttkbootstrap that essentially creates a template engine that iterates over color schemes to create over a dozen nice looking bootstrap inspired themes. I've also added a theme creator so that you can add your own color themes. |
It's crazy, but I like it 😄 I tried to make ttk themes in python several times, but I always gave up because the syntax of |
@israel-dryer Thank you for posting this message! I probably wouldn't have come across your project on my own. While I was already aware of how themes and styles can be created through Python, your project really takes that one step further and the theme looks really good! As creating themes by drawing pixmaps and such is not really my thing, I have also looked at other ways of loading themes from different sources into ttk, such as from Gtk and Qt. I've also spent some time on trying to parse Gtk-2.0 themes (which provide the base for quite some ttk themes) into a ttk theme, but the hurdles were too significant. This does make me curious though: What kind of scope are you looking to achieve with your project? Because I've been working on getting If you're looking to do something similar, I might focus my efforts elsewhere. Regardless, I'll be watching your project with interest! |
Yeah, the syntax is a mess... I try to use as few images as possible on widgets that are expandable because this seems to cause the greatest amount of lag. I made the mistake of using a 1x1 pixel image for the Another interesting strategy is building a hybrid widget layout by using elements from various themes. When creating a combobox (and spinbox), I wanted to create a border effect around the entire widget while removing the border from the combobox button. In order to do this, I used the arrow from the default theme so that I could set settings = {
'Combobox.downarrow': {'element create': ('from', 'default')},
'Combobox.padding': {'element create': ('from', 'clam')},
'Combobox.textarea': {'element create': ('from', 'clam')}
} |
oh, I would love to be able to use svg natively in Tkinter! I've heard that it's added in the 8.7 edition of tcl/tk, but that version is not yet shipped in python as far as I know. As far as scope, my intent is to create a package that has a general thematic style which can be applied to any combination of colors. So, anything I build would need to be as generic as possible with regards to extra features. The theme creation functionality is more about allowing users to select colors for a predefined style structure than anything else. I probably won't add anything else beyond that at this point. Though, depending on how the svg stuff turns out... it could definitely be a replacement for the pillow images I'm currently drawing at runtime. |
If you want to use SVG, use this: https://github.com/TkinterEP/python-tksvg |
Hi everybody.
I see themes are created using tcl code but project is thought as python package.
Is there any plan to create themes in a pythonic way? I mean, using style functions that already exists in python Tk library. I was playing with this and found windows render much more fast than actual implementation.
Thank you.
The text was updated successfully, but these errors were encountered: