[英]Updating a value in a Python TKinter Entry Box
I'm using Python 3.8.1 with tkinter version 8.6.我正在使用 Python 3.8.1 和 tkinter 8.6 版。
I have a GUI class, Pressureinput
, which takes in input for a pressure sensor simulator.我有一个 GUI 类
Pressureinput
,它接收压力传感器模拟器的输入。 I want the entry to be in units of kPa (native units of the sensor) but I also want the user to know what the psi equivalent is.我希望条目以 kPa 为单位(传感器的本机单位),但我也希望用户知道 psi 等效值是多少。 So, when the user updates the kpa value, I want the psi value to update, but I don't want the user to be able to update the psi value manually.
因此,当用户更新 kpa 值时,我希望 psi 值更新,但我不希望用户能够手动更新 psi 值。 I'm using an entry box for both.
我正在为两者使用一个输入框。 They start with a default of 242 kPa.
它们以默认值 242 kPa 开始。
I'm trying to use validate="focusout"
to trigger an event after the kpa entry box loses focus.我正在尝试使用
validate="focusout"
在 kpa 输入框失去焦点后触发事件。
Here's my code so you can see what I'm trying to do.这是我的代码,因此您可以看到我正在尝试做什么。 Basically, if they enter anything that's not a positive, even integer, I want it to automatically round the value in the entry box and then I also want it to update the psi equivalent.
基本上,如果他们输入的任何内容不是正数,甚至不是整数,我希望它自动舍入输入框中的值,然后我还希望它更新 psi 等效值。
I realize the method I'm using with my pressurevalid
function won't work because the entrybox objects, kpa and psi are immutable and it won't change the original objects.我意识到我与
pressurevalid
函数一起使用的方法将不起作用,因为 entrybox 对象 kpa 和 psi 是不可变的,它不会更改原始对象。
Note that I've set up the StringVar variables psitext
and kpatext
.请注意,我已经设置了 StringVar 变量
psitext
和kpatext
。 Every time I try to use them in my pressurevalid
function, however, I get errors saying they don't exist.然而,每次我尝试在我的
pressurevalid
函数中使用它们时,我都会收到错误消息,说它们不存在。
Everything else I've tried ends up with errors that won't run, and I think this at least illustrates what I want to do:我尝试过的其他一切都以无法运行的错误告终,我认为这至少说明了我想要做的事情:
import tkinter as tkGUI
#global constants for conversion
global psi2kpa
global kpa2psi
psi2kpa = 6.894757
kpa2psi = 1 / psi2kpa
class Pressureinput(tkGUI.Frame):
def __init__(self,parent):
tkGUI.Frame.__init__(self,parent)
self.parent = parent
self.initialize()
def initialize(self):
kpatext = tkGUI.StringVar()
psitext = tkGUI.StringVar()
self.IDlabel = tkGUI.Label(self,text="Sensor ID (hex):")
self.IDlabel.grid(row=0, column=0)
self.ID = tkGUI.Entry(self)
self.ID.insert(0,"AABBCCDD")
self.ID.grid(row=0, column=1)
self.kpalabel = tkGUI.Label(self,text="Pressure (kPa):")
self.kpalabel.grid(row=1, column=0)
self.kpa = tkGUI.Entry(self)
self.kpa.insert(0,242)
self.kpa.grid(row=1, column=1)
self.psilabel = tkGUI.Label(self,text="Pressure (PSI):")
self.psilabel.grid(row=2, column=0)
self.psi = tkGUI.Entry(self, textvariable=psitext)
self.psi.insert(0,float(self.kpa.get())*kpa2psi)
self.psi.grid(row=2, column=1)
self.psi.config(state='disabled') #state = 'normal' to restore
vpressure = self.register(self.pressurevalid(self.kpa,self.psi))
self.kpa = tkGUI.Entry(self, textvariable=kpatext, validate="focusout", validatecommand=vpressure)
self.sendbutton = tkGUI.Button(self,text="Send Transmission",state="disabled",command=self.send_data)
self.sendbutton.grid(row=9,columnspan=2)
def pressurevalid(self,kpa,psi):
if len(kpa.get()) < 1:
kpa.delete(0,tkGUI.END)
kpa.insert(0,"0");
elif 2*int(round(float(kpa.get())) / 2) != int(kpa.get()):
kpa.delete(0,tkGUI.END)
kpa.insert(0,2 * int(round(float(kpa.get()))) / 2)
psi.config(state='normal')
psi.delete(0,tkGUI.END)
psi.insert(0,float(kpa.get())*kpa2psi)
psi.config(state='disabled')
return True
def send_data(self):
ID = int(self.ID.get(),16)
pressure = int(self.kpa.get())
if pressure >= 510:
pressure = 255
else:
pressure = int(round(pressure/2))
sendstring = str(ID) + "," + str(function_code) + "," + str(pressure)
print (sendstring)
Since you are using a StringVar
for the entries, you can set up a trace on the variable to call a function whenever the value changes.由于您使用
StringVar
作为条目,您可以在变量上设置跟踪以在值更改时调用函数。 This will constantly keep the value updated rather than waiting for a focus-out event.这将不断更新值,而不是等待焦点移出事件。
First, you need to convert the variables into attributes of the class rather than making them local variables:首先,您需要将变量转换为类的属性,而不是将它们设为局部变量:
self.kpatext = tkGUI.StringVar()
self.psitext = tkGUI.StringVar()
You'll also have to adjust other places which reference these variables:您还必须调整引用这些变量的其他地方:
self.psi = tkGUI.Entry(..., textvariable=self.psitext, ...)
self.kpa = tkGUI.Entry(..., textvariable=self.kpatext, ...)
Next, set up a trace on self.kpatext
right after you create the variables:接下来,在创建变量后立即在
self.kpatext
上设置跟踪:
self.kpatext.trace("w", self.update_psi)
And finally, write the method self.update_psi
.最后,编写方法
self.update_psi
。 The following code will set the PSI to an empty string if the current value of kPa isn't able to be converted.如果无法转换 kPa 的当前值,以下代码会将 PSI 设置为空字符串。
def update_psi(self, *args):
try:
psi = int(self.kpatext.get())*kpa2psi
self.psitext.set(psi)
except Exception as e:
self.psitext.set("")
For more information on what the arguments to the trace function are, see What are the arguments to Tkinter variable trace method callbacks?有关跟踪函数的参数是什么的更多信息,请参阅Tkinter 变量跟踪方法回调的参数是什么? .
. In this example we don't need them, but the function still must accept them.
在这个例子中,我们不需要它们,但函数仍然必须接受它们。
Note, your code defines self.kpa
twice -- once without using textvariable
and once with.请注意,您的代码定义了
self.kpa
两次——一次不使用textvariable
,一次使用。 I don't understand why you're doing that given that the second one is never added to the screen with pack/place/grid.我不明白你为什么要这样做,因为第二个从来没有用包装/放置/网格添加到屏幕上。 My solution works under the assumption that the original
self.kpa
is the one that you intend to use.我的解决方案假设原始
self.kpa
是您打算使用的那个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.