[Tkinter-discuss] Fwd: Toggle buttons

Jane Griscti jgriscti at gmail.com
Tue Jul 24 20:50:36 CEST 2012


---------- Forwarded message ----------
From: Jane Griscti <jgriscti at gmail.com>
Date: Tue, Jul 24, 2012 at 1:37 PM
Subject: Re: [Tkinter-discuss] Toggle buttons
To: Mark Summerfield <list at qtrac.plus.com>



On Tue, Jul 24, 2012 at 11:05 AM, Mark Summerfield <list at qtrac.plus.com>wrote:

> Hi Jane,
>
> On Tue, 24 Jul 2012 13:45:38 +0000 (UTC)
> Jane <jgriscti at gmail.com> wrote:
> > Mark Summerfield <list <at> qtrac.plus.com> writes:
> >
> > >
> > > Hi,
> > >
> > > I want to create a toggle button, i.e., a button that when clicked goes
> > > down (if it is up) and goes up (if it is down).
> > >
> > > One easy way to achieve this is to set the button's style to
> > > "Toolbutton" (see self.toggle2). But unfortunately, that gets rid of
> > > the button's relief so it looks out of place amongst other non-toggling
> > > buttons.
> > >
> > > I solved if for Linux using a custom style (see self.toggle3). But this
> > > doesn't work on Windows and I can't figure out how to solve it.
> > >
> > > Can anyone suggest a solution?
> [snip]
>
> > Hi ...
> >
> > Found that setting the ttk.Checkbutton style to 'TButton' forces it to
> > appear as themed button; then, on selection, changing it to 'Toolbutton'
> > gives it a 'sunken' appearance. Works ok under Windows 7.
> >
> >     cb1 = ttk.Checkbutton(f, style='Demo.TButton',
> >                              image=(self.noletters, 'selected',
> > self.letters), command=lambda: self._cb_value_changed(cb1))
> >
> >     def _cb_value_changed(self, cb):
> >         # if a checkbutton is selected, use the 'Toolbutton'
> >         # style to make it appear 'sunken'
> >         if 'selected' in cb.state():
> >             cb['style'] = 'Demo.Toolbutton'
> >         else:
> >             cb['style'] = 'Demo.TButton'
>
> I tried your idea on Windows 7 & Linux (& a slightly simplified version
> which did the same). Yes, it correctly changes the appearance between
> raised and sunken: but in the sunken state the width of the button
> shrinks to fit the text -- and there's no width property for styled
> buttons:-(
>
> Here's the code:
>
> ############################################################
> import tkinter.ttk
>
> class Window(tkinter.ttk.Frame):
>
>     def __init__(self, master=None):
>         super().__init__(master)
>         self.toggle1 = tkinter.ttk.Button(self, text="Off (1)",
>                 command=lambda *args: self.toggle(self.toggle1, 1))
>         self.toggle1.pack(padx=5, pady=5)
>         self.toggle2 = tkinter.ttk.Button(self, text="Off (2)",
>                 style="Toolbutton",
>                 command=lambda *args: self.toggle(self.toggle2, 2))
>         self.toggle2.pack(padx=5, pady=5)
>         self.toggle3 = tkinter.ttk.Button(self, text="Off (3)",
>                 command=lambda *args: self.toggle(self.toggle3, 3))
>         self.toggle3.pack(padx=5, pady=5)
>         style = tkinter.ttk.Style()
>         style.configure("Toggle.TButton")
>         style.map("Toggle.TButton", relief=[("pressed", "sunken"),
>             ("selected", "sunken"), ("!selected", "raised")])
>         self.toggle3.config(style="Toggle.TButton")
>         self.toggle4 = tkinter.ttk.Checkbutton(self,
>                 style="Toggle.TButton", text="Off (4)",
>                 command=lambda *args: self.toggle_style(self.toggle4, 4))
>         self.toggle4.pack(padx=5, pady=5)
>         tkinter.ttk.Button(self, text="Quit",
>                 command=self.master.destroy).pack(padx=5, pady=5)
>         self.pack()
>
>     def toggle_style(self, button, number):
>         if button.instate(("selected",)):
>             button.config(text="Off ({})".format(number))
>             button.config(style="Toolbutton")
>         else:
>             button.config(text="On ({})".format(number))
>             button.config(style="Toggle.TButton")
>
>     def toggle(self, button, number):
>         if button.instate(("!selected",)):
>             button.state(("selected",))
>             button.config(text="On ({})".format(number))
>         else:
>             button.state(("!selected",))
>             button.config(text="Off ({})".format(number))
>
> window = Window()
> window.master.title("Toggle")
> window.master.mainloop()
> ############################################################
>
>
> --
> Mark Summerfield, Qtrac Ltd, www.qtrac.eu
>     C++, Python, Qt, PyQt - training and consultancy
>         "Programming in Go" - ISBN 0321774639
>             http://www.qtrac.eu/gobook.html
>

Hi Mark ... there is a width value for ttk.Checkbutton.

I was able to get it work with the code below.  I just forced a width of 11
pixels (tried to use the winfo_reqwidth() of another button to get the
right size but it returns 76 for some reason ... there must be a way to get
a decent size??)


        tkinter.ttk.Style().configure('Toggle.Toolbutton', anchor='center')
        self.toggle4 = tkinter.ttk.Checkbutton(self,
                style='Toggle.TButton', text="Off (4)", width=-11,
                command=lambda *args: self.toggle_style(self.toggle4, 4))
        self.toggle4.pack(padx=5, pady=5)

    def toggle_style(self, button, number):
        if button.instate(("selected",)):
            button.config(text="Off ({})".format(number))
            button.config(style="Toggle.Toolbutton")
        else:
            button.config(text="On ({})".format(number))
            button.config(style="Toggle.TButton")

Jane

PS Apologies, thought I had sent this to the list
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tkinter-discuss/attachments/20120724/735c0852/attachment-0001.html>


More information about the Tkinter-discuss mailing list