4

I'm trying to make a entry value increase or decrease whenever the up or down arrow key is pressed. To do this i need to first find which entry that's in focus, and i'm trying to do that ".focus_get()". The problem is that i can't figure out how it works or what its returning. It is returning 1 unique number for each entry, something like: ".45191744" but this number changes each time i run the program. The following numbers is for the last 5 attempts, when running the code. ".50518728" ".53009096" ".55889592" ".51891896"

How can i get the variable name of the focused entry?

Here is my code:

def get_focus1(event):
    print("return: event.widget is", event.widget)
    print("focus is:", window2.focus_get())
    print(window2.focus_get())
    print(help(window2.Entry))

window2 = Tk()

eyear1 = Entry(window2, width=4, font=("Helvetica", 16)) #  Entry for year
eyear1.insert(10, defaultYear)
eyear1.grid(row=1, column=1)

emonth1 = Entry(window2, width=4, font=("Helvetica", 16)) #  Entry for Month
emonth1.insert(10, defaultMonth)
emonth1.grid(row=1, column=2)

eday1 = Entry(window2, width=4, font=("Helvetica", 16)) #  Entry for day
eday1.insert(10, defaultDay)
eday1.grid(row=1, column=3)

window2.bind('<Left>', get_focus1)

mainloop()
Cœur
  • 37,241
  • 25
  • 195
  • 267
RasmusGP
  • 4,696
  • 5
  • 21
  • 28

2 Answers2

5

focus_get returns the actual object. What you want to do, assuming your not using textvariable for a good reason (see Bryan's comment), is to clear the text and re-write the new value (do some validation obviously). What you end up is something like this:

from tkinter import *

def up(event):
    # warning, exceptions can happen
    old = int(event.widget.get()) # this gives back the actual object!
    event.widget.delete(0, END) # delete existing text
    event.widget.insert(10, old + 1) # put new text in

def down(event):
    # warning, exceptions can happen
    old = int(event.widget.get()) # this gives back the actual object!
    event.widget.delete(0, END) # delete existing text
    event.widget.insert(10, old - 1) # put new text in

window2 = Tk()

eyear1 = Entry(window2, width=4, font=("Helvetica", 16)) #  Entry for year
eyear1.insert(10, 2015)
eyear1.grid(row=1, column=1)

emonth1 = Entry(window2, width=4, font=("Helvetica", 16)) #  Entry for Month
emonth1.insert(10, 1)
emonth1.grid(row=1, column=2)

eday1 = Entry(window2, width=4, font=("Helvetica", 16)) #  Entry for day
eday1.insert(10, 10)
eday1.grid(row=1, column=3)

# bind both keys to corresponding event handlers
window2.bind('<Up>', up)
window2.bind('<Down>', down)
mainloop()
Reut Sharabani
  • 30,449
  • 6
  • 70
  • 88
  • 1
    The good reason for not using textvariable is that textvariable is completely unnecessary in most circumstances. It adds a tiny bit of complexity for no real gain in most circumstances (where "complexity" is defined as "creating more objects than you really need"). – Bryan Oakley Jan 09 '15 at 20:01
  • @BryanOakley I'm not experienced with `Tkinter`, so I'll take your word for it :) That's what I saw people use, so I'll remove it. – Reut Sharabani Jan 09 '15 at 20:02
  • 1
    @RasmusGP make sure you do some checking, since it can easily break. This was just to make a point. Good luck. – Reut Sharabani Jan 09 '15 at 20:07
2

Remember that when you call print, you are getting the representation of an object, not necessarily the object itself. To show you what's going on, add this to your get_focus1 function:

print("focus object class:", window2.focus_get().__class__)

You should see that it is indeed returning a reference to an Entry widget, meaning you can call all the normal methods on that object.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I see, this might be a stupid question, but how to i get the entry name of that entry? i need to change the text in it – RasmusGP Jan 09 '15 at 19:56
  • 3
    @RasmusGP: you don't need the entry name, `event.widget` _is_ the widget: `widget=event.widget; value=widget.get()` – Bryan Oakley Jan 09 '15 at 19:58
  • But my problem now is that i have to be able to set a limit to that entry like, the "emonth1" entry shouldn't be able to get higher then 12. So i need a way to check whether its a year, month, day, hour or minute entry. I could hardcode it but i have 2 of each entry, so i would love to be able to get the variable name. – RasmusGP Jan 09 '15 at 21:20
  • @RasmusGP: You can add a custom attribute to each widget, for example `emonth1.limit=12`. Then you can later fetch that limit in the hander with `event.widget.limit`. – Bryan Oakley Jan 09 '15 at 21:25
  • How does that work? when i try this: `emonth1 = Entry(window2, width=4, font=("Helvetica", 16), limit = 12)` it says unknown option. And when i do `emonth1.limit=12`it nothing happens. does it prevent the value to get higher then 12? – RasmusGP Jan 09 '15 at 21:41
  • @RasmusGP: you get an error because `font`, `width`, etc. are _built-in_ attributes, `limit` is a _custom_ attribute. You can't use custom attributes the way you use built-in attributes. When you do `emonth.limit=12`, it does _not_ do nothing: it sets an attribute named `limit` on the object referenced by `emonth1`. – Bryan Oakley Jan 09 '15 at 21:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/68523/discussion-between-rasmusgp-and-bryan-oakley). – RasmusGP Jan 09 '15 at 22:03