Home > Enterprise >  Linking tkinter entries to each others input
Linking tkinter entries to each others input

Time:09-29

I'm trying to make 2 entries display strings based on each others input. E.g if I type 10 in the entry1 entry2 displays 10*2, same for entry2 but entry1 must display 10/2. I tried:

from tkinter import *
from tkinter import ttk

root = Tk()

root.geometry("700x350")
varEntry1=StringVar()
varEntry2=StringVar()

varEntry1.trace('w', lambda name, index, mode, varEntry1=varEntry1: callback(varEntry1))
varEntry2.trace('w', lambda name, index, mode, varEntry2=varEntry2: callback2(varEntry2))



entry1 = ttk.Entry(root,textvariable=varEntry1)
entry2 = ttk.Entry(root,textvariable=varEntry2)


def callback(varEntry1):
  
    print (varEntry1.get())
    entry2.delete(0,END)
    entry2.insert(0,float(varEntry1.get())*2)

def callback2(varEntry2):
  
    print (varEntry2.get())
    entry1.delete(0,END)
    entry1.insert(0,float(varEntry2.get())/2)



entry1.pack()
entry2.pack()

But it seems like entry tracings mess with each other and input gets deleted after I type 2nd symbol. Then i tried to create function that will disable trace for entry2 on click on entry1 but it didn't work. Is there more elegant way to achieve this?

CodePudding user response:

Here is a way to do this:

from tkinter import *
from tkinter import ttk

root = Tk()

root.geometry("700x350")
varEntry1=StringVar()
varEntry2=StringVar()

entry1 = ttk.Entry(root,textvariable=varEntry1)
entry2 = ttk.Entry(root,textvariable=varEntry2)

def callback(event): ### EDITED LINE

    print(varEntry1.get())
    entry2.delete(0,END)
    entry2.insert(0,float(varEntry1.get())*2)

def callback2(event): ### EDITED LINE

    print(varEntry2.get())
    entry1.delete(0,END)
    entry1.insert(0,float(varEntry2.get())/2)

entry1.bind("<Return>", callback) ### ADDED LINE
entry2.bind("<Return>", callback2) ### ADDED LINE

entry1.pack()
entry2.pack()

root.mainloop()

This uses the bind() function of the entries, so that whenever the user hits enter after typing in the entry, it performs the calculations. This way, you can type a number of any size before it calculates.

If you want to do it while still using the trace() function, you can have it perform the calculations when the user hits a certain key, such as ::

from tkinter import *
from tkinter import ttk

root = Tk()

root.geometry("700x350")
varEntry1=StringVar()
varEntry2=StringVar()

varEntry1.trace('w', lambda name, index, mode, varEntry1=varEntry1: callback(varEntry1))
varEntry2.trace('w', lambda name, index, mode, varEntry2=varEntry2: callback2(varEntry2))

entry1 = ttk.Entry(root,textvariable=varEntry1)
entry2 = ttk.Entry(root,textvariable=varEntry2)

def callback(varEntry1):
  
    if ":" in varEntry1.get():
        entry2.delete(0,END)
        entry2.insert(0,float(varEntry1.get().replace(":", ""))*2)

def callback2(varEntry2):
  
    if ":" in varEntry2.get():
        entry1.delete(0,END)
        entry1.insert(0,float(varEntry2.get().replace(":", ""))/2)

entry1.pack()
entry2.pack()

root.mainloop()

You can use any character in place of :, (I don't recommend using ., however :-)).

  • Related