[Tutor] Tkinter, the correct way
Alan Gauld
alan.gauld at yahoo.co.uk
Fri Feb 10 10:40:37 EST 2023
On 10/02/2023 09:00, Phil wrote:
> Is this code the correct modern way?
There is no such thing. Thre are many styles of tkinter programming.
"Correctness" is largely subjective (assuming the code works of course!)
> I don't notice any difference If I omit the frame padding and grid options.
That normally only makes a difference when you resize a window
near its limits(small or large).
> VS Code issues warnings to do with import *
Sensibly so. I don't think any production Tkinter code
should use import *. The style i normally see is
import tkinter as tk
or similar.
> and value_label = etc is a function without a return.
Again, correctly. The return from ttk.Label().grid() is
None so assigning it to a variable is pointless.
> Finally, moving the scale with the arrow keys show integers but moving
> the scale with the mouse cause the scale value to be a long floating
> point number. How might I have the value variable be an integer when the
> mouse is moved?
Need to read the docs(and/or Tcl/Tk code?) for the Scale widget.
> from tkinter import *
> from tkinter import ttk
>
> class ScaleDemo:
>
> def __init__(self, root):
>
> root.title("Scale Demo")
>
> frame = ttk.Frame(root, padding="3 3 12 12")
> frame.grid(column=0, row=0, sticky=(N, S, E, W))
>
> root.columnconfigure(0, weight=1)
> root.rowconfigure(0, weight=1)
>
> self.value = DoubleVar()
This might be the root of your problem. What happens if
you use an IntVar instead of a DoubleVar? But double makes
more sense for a Scale if you can set intermediate points.
> slider = ttk.Scale(
> frame,
> from_=0,
> to=100,
> orient='horizontal', # vertical
> command=self.slider_changed,
> variable=self.value)
I would have thought you might want to keep hold of the slider so
self.slider = ...
>
> slider.grid(column=2, row=1, sticky=(E, W))
>
> value_label = ttk.Label(frame, textvariable=self.value).grid(
> column=2, row=2, sticky=(W, E))
And this shouldn't work. grid() returns None.
Hence your warning from VS.
OTOH you don;t stre the value outside __init__() and never
use it inside so its totally irrelevant!
> ttk.Button(frame, text="Exit", command=root.destroy).grid(
> column=3, row=3, sticky=W)
This is the more normal approach with no variable used.
> for child in frame.winfo_children():
> child.grid_configure(padx=5, pady=5)
I'm not sure about this but it doesn't look right to me.
I prefer to have all the options supplied per widet even
if its slightly more typing (probably less in this case!)
My reasoning is that I look for the options where the
widget is created, putting some of them in a loop
which affects every widget sounds like a debugging
nightmare to me!
>
> slider.focus()
>
> def slider_changed(self, event):
> #print('value changed')
> print(f'{self.value.get():,.1f}')
Is this the bit where you get the int/double issue?
If so I suspect the arrow keys move the slider in unit amounts hence
integers and the mouse moves it in a contuinuous manner and returns
doubles. ie What I'd expect. But I've never used a ttk.slider so
don't know.
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos
More information about the Tutor
mailing list