# File: ttkthemes.py # References: # http://www.tcl.tk/man/tcl8.5/TkCmd/ttk_style.htm from tkinter import * from tkinter import ttk from demopanels import MsgPanel, SeeDismissPanel class ThemeDemo(ttk.Frame): def __init__(self, isapp=True, name='themesdemo'): ttk.Frame.__init__(self, name=name) self.pack(expand=Y, fill=BOTH) self.master.title('Ttk Theme Demo') self.isapp = isapp self._create_widgets() def _create_widgets(self): if self.isapp: MsgPanel(self, ["Ttk is the new Tk themed widget set. This is a Ttk themed label, ", "and below are three groups of Ttk widgets in Ttk labelframes.\n\n", "The first group are all buttons that set the current application ", "theme when pressed. Note the message box does not change as it uses ", "a standard tkinter Label to hold the message.\n", "The second group contains three sets of checkbuttons, ", "with a separator widget between the sets. ", "Note that the 'Enabled' button controls whether or not all the other ", "buttons are in the disabled state.\n", "The third group has a collection of linked radiobuttons."]) SeeDismissPanel(self) self._create_demo_panel() self.allBtns = self.ttkbut + self.cbs[1:] + self.rb def _create_demo_panel(self): demoPanel = ttk.Frame(self) demoPanel.pack(side=TOP, fill=BOTH, expand=Y) themePane = self._theme_pane(demoPanel) rbPane = self._rb_pane(demoPanel) cbPane = self._cb_pane(demoPanel) varPane = self._var_panel(demoPanel) themePane.pack(side=LEFT, expand=True, padx=10, pady=10, fill=BOTH) cbPane.pack(side=LEFT, expand=True, padx=10, pady=10,fill=BOTH) rbPane.pack(side=LEFT, expand=True, padx=10, pady=10, fill=BOTH) varPane.pack(side=LEFT, expand=True, padx=10, pady=10, fill=BOTH) def _theme_pane(self, parent): lf = ttk.Labelframe(parent, text='Themes') themes = sorted(ttk.Style().theme_names()) self.ttkbut = [] for t in themes: b = ttk.Button(lf, text=t, command=lambda t=t: ttk.Style().theme_use(t)) b.pack(pady=2) self.ttkbut.append(b) return lf def _cb_pane(self, parent): lf = ttk.Labelframe(parent, text='Checkbuttons') # control variables self.enabled = IntVar() self.cheese = IntVar() self.tomato = IntVar() self.basil = IntVar() self.oregano = IntVar() # checkbuttons self.cbOpt = ttk.Checkbutton(lf, text='Enabled', variable=self.enabled, command=self._toggle_opt) cbCheese = ttk.Checkbutton(text='Cheese', variable=self.cheese, command=self._show_vars) cbTomato = ttk.Checkbutton(text='Tomato', variable=self.tomato, command=self._show_vars) sep1 = ttk.Separator(orient=HORIZONTAL) cbBasil = ttk.Checkbutton(text='Basil', variable=self.basil, command=self._show_vars) cbOregano = ttk.Checkbutton(text='Oregano', variable=self.oregano, command=self._show_vars) sep2 = ttk.Separator(orient=HORIZONTAL) self.cbs = [self.cbOpt, sep1, cbCheese, cbTomato, sep2, cbBasil, cbOregano] for opt in self.cbs: if opt.winfo_class() == 'TCheckbutton': opt.configure(onvalue=1, offvalue=0) opt.setvar(opt.cget('variable'), 0) opt.pack(in_=lf, side=TOP, fill=X, pady=2, padx=5, anchor=W) return lf def _rb_pane(self, parent): lf = ttk.Labelframe(parent, text='Radiobuttons', labelanchor=N+S) self.rb=[] self.happiness = StringVar() for s in ['Great', 'Good', 'OK', 'Poor', 'Awful']: b = ttk.Radiobutton(lf, text=s, value=s, variable=self.happiness, command=lambda s=s: self._show_vars()) b.pack(side=TOP, fill=X, pady=2) self.rb.append(b) return lf def _var_panel(self, parent): # panel to display check button variable values right = ttk.LabelFrame(parent, text='Control Variables') self.vb0 = ttk.Label(right, font=('Courier', 10)) self.vb1 = ttk.Label(right, font=('Courier', 10)) self.vb2 = ttk.Label(right, font=('Courier', 10)) self.vb3 = ttk.Label(right, font=('Courier', 10)) self.vb4 = ttk.Label(right, font=('Courier', 10)) self.vb5 = ttk.Label(right, font=('Courier', 10)) self.vb0.pack(anchor=NW, pady=3) self.vb1.pack(anchor=NW, pady=3) self.vb2.pack(anchor=NW, pady=3) self.vb3.pack(anchor=NW, pady=3) self.vb4.pack(anchor=NW, pady=3) self.vb5.pack(anchor=NW, pady=3) self._show_vars() return right def _show_vars(self): # set text for labels in var_panel to include the control # variable name and current variable value self.vb0['text'] = '{:<11} {:<8}'.format('enabled:', self.enabled.get()) self.vb1['text'] = '{:<11} {:<8}'.format('cheese:', self.cheese.get()) self.vb2['text'] = '{:<11} {:<8}'.format('tomato:', self.tomato.get()) self.vb3['text'] = '{:<11} {:<8}'.format('basil:', self.basil.get()) self.vb4['text'] = '{:<11} {:<8}'.format('oregano:', self.oregano.get()) self.vb4['text'] = '{:<11} {:<8}'.format('happiness:', self.happiness.get()) def _toggle_opt(self): # state of the option buttons controlled # by the state of the Option frame label widget for opt in self.allBtns: if opt.winfo_class() != 'TSeparator': if self.cbOpt.instate(('selected', )): opt['state'] = '!disabled' # enable option else: opt['state'] = 'disabled' self._show_vars() if __name__ == '__main__': ThemeDemo().mainloop()
Wednesday, July 25, 2012
Tkinter Themes Demo
This code is based on the Tcl ttkbut.tcl demo. The available Ttk themes are displayed in the Themes panel; clicking a button changes the overall theme of the window.
Labels:
Tkinter Demos