Tkinter binding question

Frederic Rentsch anthra.norell at bluewin.ch
Wed Jun 20 13:07:04 EDT 2012


On Tue, 2012-06-19 at 19:19 -0700, rantingrickjohnson at gmail.com wrote:
> On Tuesday, June 19, 2012 10:55:48 AM UTC-5, Frederic Rentsch wrote:
> > If I copy your event descriptors into my program, the button-release
> > callback still fails. It works in your code, not in mine. Here is what
> > my code now looks like. It is somewhat more complicated than yours,
> > because I bind Frames holding each a line (line_frame) and each frame
> > contains a few Labels side by side. The idea is to achieve a table with
> > vertically aligning columns each line of which I can click-select. (Is
> > there a better way?)
> > 
> >    for line_frame in ...:
> >       line_frame.bind ('<Enter>', self.color_selected)
> >       line_frame.bind ('<Leave>', self.color_selectable)
> >       line_frame.bind ('<ButtonRelease-1>', self.pick_record)
> >       line_frame.bind ('<ButtonRelease-3>', self.info_profile)
> >       line_frame.grid (row = n+1, column = 0)
> >       for i in self.range_n_fields:
> >          field = Label (line_frame, width = ..., text = ...    
> >          field.grid (row = 0, column = i, sticky = W)
> >       ...
> > 
> >    def color_selected (self, event):
> >       print 'hit list.color_selected ()'
> > 
> >    def color_selectable (self, event):
> >       print 'hit list.color_selectable ()'
> > 
> >    def pick_record (self, event):     # Nver gets called
> >       print 'hit list.pick_record ()'
> > 
> >    def info_profile (self, event):    # Never gets called
> >       print 'hit list.info_profile ()'
> 
> Events only fire for the widget that currently has "focus". Frames, labels, and other widgets do not receive focus simply by hovering over them. You can set the focus manually by calling "w.focus_set()" -- where "w" is any Tkinter widget. I can't be sure because i don't have enough of your code to analyze, but I think you should bind (either globally or by class type) all "Enter" events to a callback that sets the focus of the current widget under the mouse. Experiment with this code and see if it is what you need:
> 
> ## START CODE ##
> from __future__ import print_function
> import Tkinter as tk
> 
> def cb(event):
>     print(event.widget.winfo_class())
>     event.widget.focus_set()
> 
> root = tk.Tk()
> root.geometry('200x200+20+20')
> for x in range(10):
>     w = tk.Frame(root, width=20, height=20,bg='red')
>     w.grid(row=x, column=0, padx=5, pady=5)
>     w = tk.Frame(root, width=20, height=20,bg='green', highlightthickness=1)
>     w.grid(row=x, column=1, padx=5, pady=5)    
>     w = tk.Button(root, text=str(x))
>     w.grid(row=x, column=2, padx=5, pady=5)
> root.bind_all("<Enter>", cb)    
> root.mainloop()
> ## END CODE ##
> 
> You will see that the first column of frames are recieving focus but you have no visual cues of that focus (due to a default setting). In the second column you get the visual cue since i set "highlightthicness=1". The third column is a button widget which by default has visual focus cues.
> 
> Is this the problem? 

Yes, I was unaware of focus control. I understand that it is set either
by a left mouse button click or the method focus_set ().  

> PS: Also check out the "w.bind_class()" method.
> 
> > Incidentally, my source of inspiration for chaining event descriptors
> > was the New Mexico Tech Tkinter 8.4 reference, 
> 
> That's an excellent reference BTW. Keep it under your pillow. Effbot also has a great tutorial.


Thanks for this additional load af advice.

Googling I chanced on an excellent introduction "Thinking in Tkinter" by
Stephen Ferg.
(http://www.ferg.org/thinking_in_tkinter/all_programs.html). He sets out
identifying a common problem with tutorials: The problem is that the
authors of the books want to rush into telling me about all of the
widgets in the Tkinter toolbox, but never really pause to explain basic
concepts. They don't explain how to "think in Tkinter".
	He then explains seventeen functionalities, one at a time, and
illustrates them with a little piece of code ready to run. Working
through the examples is a good way to acquire a basic understanding
without falling victim to "brain clutter". I shall go through the
examples very attentively and go on from there.

Thanks again

Frederic





More information about the Python-list mailing list