first post but long time listener...
I'm new to tkinter and am running into some issues. Main one that has me scratching my head is that when I enter a value into one of the 4 input boxes then they duplicate the value in the other 4 boxes. Buttons are working OK, and I need to clean things up but not sure if this is a valid approach:
Also the frames are wrong and I plan to add comments
I removed some extraneous lines but got the same results. Added self to the text variable in the Entry object.
import tkinter as tk
from tkinter import *
from tkinter import ttk
root = Tk()
s = ttk.Style()
s.configure('Danger.TFrame', background='red', borderwidth=5, relief='sunken')
frm = ttk.Frame(root, padding=200, style='Danger.TFrame').grid()
#Fix needed for inputs duplicating.
input_frame = ttk.Frame(frm,padding=10).grid(row=1)
output_frame = ttk.Frame(frm,padding=10).grid(row=16,column=0)
class single_frame(tk.Frame): #intent is to have repeatable frame with name, abreviation, and unit
def __init__(self, parent, name, abreviation, unit,row_adjust) -> None:
self.n = name
self.u = unit
self.a = abreviation
ttk.Frame(parent, width = 50, height = 50,style='Danger.TFrame').grid()
ttk.Label(parent,text=self.n).grid(column=0, row=row_adjust)
ttk.Label(parent,text=self.a).grid(column=1,row=row_adjust)
ttk.Label(parent,text=self.u).grid(column=3,row=row_adjust)
pass
class fxinput(single_frame): #setting up a class to handle input boxes
def __init__(self,parent,name,abreviation,unit,row_adjust) -> None:
super().__init__(parent,name,abreviation,unit,row_adjust)
self.v = float()
self.e = ttk.Entry(parent, textvariable=self.v)
#self.e.insert(tk.END,"1")
self.e.grid(column=2,row=row_adjust)
pass
class fxoutput(single_frame): #setting up a class to handle input boxes
def __init__(self,parent,name,abreviation,unit,out,row_adjust) -> None:
super().__init__(parent,name,abreviation,unit,row_adjust)
self.out = out
self.l = ttk.Label(parent, text=self.out)
self.l.grid(column=2,row=row_adjust)
pass
def update(self,value):
self.l["text"]=value
inV = fxinput(input_frame,'Ideal Gas','v','L*atm/mol*K',1)
inn = fxinput(input_frame,'Ideal Gas','n','L*atm/mol*K',2)
inT = fxinput(input_frame,'Ideal Gas','T','L*atm/mol*K',3)
inR = fxinput(input_frame,'Ideal Gas','R','L*atm/mol*K',4)
out1 = fxoutput(output_frame,'Pressure','P','atm',1, 5)
ttk.Button(frm, text="Quit!", command=root.destroy).grid(column=10,row=0)
def calculate():
try:
v = float(inV.e.get())
n = float(inn.e.get())
R = float(inR.e.get())
T = float(inT.e.get())
print(v)
p = n*R*T/v
out1.update(p)
print(out1.out)
except:
print("error")
return
calc_button = ttk.Button(frm, text="Calculate", default="active", command=calculate)
calc_button.grid(column=20,row =20)
#root.bind('<Return>', lambda e: calc_button.invoke())
root.mainloop()
Main one that has me scratching my head is that when I enter a value into one of the 4 input boxes then they duplicate the value in the other 4 boxes.
That instantly tells me that all four share the same textvariable
.
When you assign a value to the textvariable
attribute it needs to be one of the tkinter variable objects (StringVar
, IntVar
, etc). The string value of the objects name is associated with a variable internal to the embedded tcl interpreter. The name of each instance will be unique, giving you unique variables in the tcl interpreter.
However, in your case you're passing in the value of float()
. float()
returns 0.0
, so all of your widgets are going to be associated with a variable with the internal name 0.0
.
The simple fix is to use a proper tkinter variable rather than a float. For example, DoubleVar
:
class fxinput(single_frame): #setting up a class to handle input boxes
def __init__(self,parent,name,abreviation,unit,row_adjust) -> None:
...
self.v = tk.DoubleVar()
self.e = ttk.Entry(parent, textvariable=self.v)
...
In some commented out code it appears you intend to initialize the value to 1
. You can do that when creating the variable:
self.v = tk.DoubleVar(value=1.0)