tkinter 输入字段自动更新
tkinter Entry Field Auto Update
每次单击鼠标左键,self.LEFT_MB_Counter
都会递增,因此该值始终在变化。我希望 self.LEFT_MB_Counter
中的值显示在输入字段 self.left_MB_entry
中,但我无法实现。
如何让输入字段始终更新并显示 self.LEFT_MB_Counter
中的当前值?
from win32api import GetKeyState
import tkinter.ttk
import tkinter
class MainApplication:
"""Class that creates the widgets and window."""
def __init__(self, master):
"""Method that creates the class constructor."""
self.master = master
self.var = tkinter.IntVar(value=0)
self.left_MB_entry = self.Entry(self.var)
self.left_MB_entry.grid()
def Entry(self, text_var, justify="center"):
"""Method that defines a default entry field."""
entry = tkinter.ttk.Entry(self.master, textvariable=text_var, justify=justify)
return entry
class MouseCounter:
"""Class that counts mouse button clicks."""
def __init__(self):
"""Method that creates the class constructor."""
self.LEFT_MB = 0x01 # Virtual-key code from Microsoft for LEFT MButton
self.Old_State_LEFT_MB = GetKeyState(self.LEFT_MB) # LEFT MButton Down = -127 or -128, MButton Up = 0 or 1
self.LEFT_MB_Counter = 0 # Initialize to 0
def count(self):
# Following block of code monitors LEFT MButton
New_State_LEFT_MB = GetKeyState(self.LEFT_MB)
if New_State_LEFT_MB != self.Old_State_LEFT_MB: # Button state changed
self.Old_State_LEFT_MB = New_State_LEFT_MB
print(New_State_LEFT_MB)
if New_State_LEFT_MB < 0:
self.LEFT_MB_Counter += 1
print("Count:", self.LEFT_MB_Counter)
print('Left Button Pressed')
else:
print('Left Button Released')
root.after(1, self.count)
root = tkinter.Tk()
root.style = tkinter.ttk.Style()
# ('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
root.style.theme_use("clam")
APP = MainApplication(root) # Create object instance of the user interface
root.after(0, MouseCounter().count())
root.mainloop() # Display the user interface
一个选择是使 LEFT_MB_Counter
成为 IntVar
可以被 Entry
:
直接使用
from multiprocessing import Process, Pipe
import time
from win32api import GetKeyState
import tkinter.ttk
import tkinter
class MainApplication(object):
"""Class that creates the widgets and window."""
def __init__(self, master):
"""Method that creates the class constructor."""
self.master = master
self.mc = MouseCounter(master)
root.after(0, self.mc.count)
self.left_MB_entry = self.Entry(self.mc.LEFT_MB_Counter)
self.left_MB_entry.grid()
def Entry(self, text_var, justify="center"):
"""Method that defines a default entry field."""
entry = tkinter.ttk.Entry(self.master, textvariable=text_var, justify=justify)
return entry
class MouseCounter:
"""Class that counts mouse button clicks."""
def __init__(self, master):
"""Method that creates the class constructor."""
self.master = master
self.LEFT_MB = 0x01 # Virtual-key code from Microsoft for LEFT MButton
self.Old_State_LEFT_MB = GetKeyState(self.LEFT_MB) # LEFT MButton Down = -127 or -128, MButton Up = 0 or 1
self.LEFT_MB_Counter = tkinter.IntVar(0) # Initialize to 0
def count(self):
# Following block of code monitors LEFT MButton
New_State_LEFT_MB = GetKeyState(self.LEFT_MB)
if New_State_LEFT_MB != self.Old_State_LEFT_MB: # Button state changed
self.Old_State_LEFT_MB = New_State_LEFT_MB
print(New_State_LEFT_MB)
if New_State_LEFT_MB < 0:
self.LEFT_MB_Counter.set(self.LEFT_MB_Counter.get() + 1)
print("Count:", self.LEFT_MB_Counter.get())
print('Left Button Pressed')
else:
print('Left Button Released')
self.master.after(1, self.count)
root = tkinter.Tk()
root.style = tkinter.ttk.Style()
root.style.theme_use("clam")
APP = MainApplication(root)
root.mainloop() # Display the user interface
您可以通过在 MouseCounter.count()
方法中更新 MainApplication
实例的名为 APP.var
的 IntVar
属性轻松地做到这一点。
这是您的代码的修改版本,展示了如何执行此操作:
from win32api import GetKeyState
import tkinter.ttk
import tkinter
class MainApplication:
"""Class that creates the widgets and window."""
def __init__(self, master):
"""Method that creates the class constructor."""
self.master = master
self.var = tkinter.IntVar(value=0)
self.left_MB_entry = self.Entry(self.var)
self.left_MB_entry.grid()
def Entry(self, text_var, justify="center"):
"""Method that defines a default entry field."""
entry = tkinter.ttk.Entry(self.master, textvariable=text_var, justify=justify)
return entry
class MouseCounter:
"""Class that counts mouse button clicks."""
def __init__(self, variable):
"""Method that creates the class constructor."""
self.LEFT_MB = 0x01 # Virtual-key code from Microsoft for LEFT MButton
self.Old_State_LEFT_MB = GetKeyState(self.LEFT_MB) # LEFT MButton Down = -127 or -128, MButton Up = 0 or 1
self.LEFT_MB_Counter = 0 # Initialize to 0
self.variable = variable
self.variable.set(self.LEFT_MB_Counter)
def count(self):
# Following block of code monitors LEFT MButton
New_State_LEFT_MB = GetKeyState(self.LEFT_MB)
if New_State_LEFT_MB != self.Old_State_LEFT_MB: # Button state changed
self.Old_State_LEFT_MB = New_State_LEFT_MB
print(New_State_LEFT_MB)
if New_State_LEFT_MB < 0:
self.LEFT_MB_Counter += 1
self.variable.set(self.LEFT_MB_Counter)
print("Count:", self.LEFT_MB_Counter)
print('Left Button Pressed')
else:
print('Left Button Released')
root.after(1, self.count)
root = tkinter.Tk()
root.style = tkinter.ttk.Style()
# ('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
root.style.theme_use("clam")
APP = MainApplication(root) # Create object instance of the user interface
mouse_counter = MouseCounter(APP.var) # Create an instance outside of mainloop.
root.after(0, mouse_counter.count)
root.mainloop() # Display the user interface
解决方案概述
问题的根源很简单,MouseCounter
的实例没有引用应用程序,因此不会影响应用程序中的任何内容。这不是 tkinter 独有的东西,它只是一个基本的 python 原则。要更改对象,您需要引用对象。
一旦您确定 MouseCounter
的实例引用了 MainApplication
的实例,问题就变得很容易解决了。
解决方案详情
您需要做的第一件事是将 var
与条目小部件正确关联。您的代码将其作为位置参数传递,这不是正确的方法。您需要将变量分配给 textvariable
属性:
self.var = tkinter.IntVar(value=0)
self.left_MB_entry = self.Entry(textvariable=self.var)
接下来,您需要确保 MouseCounter
能够传递主应用程序的实例:
class MouseCounter:
"""Class that counts mouse button clicks."""
def __init__(self, master):
self.master = master
...
创建实例时,传入APP
作为MainApplication
的实例:
APP = MainApplication(root)
mc = MouseCounter(APP)
root.after(0, mc.count)
接下来,您只需从您的计数器更新 var
:
def count(self):
...
if New_State_LEFT_MB < 0:
...
self.master.var.set(self.LEFT_MB_Counter)
...
注意:您对after
的工作原理有点误解。不影响代码,但是要用的话还是要正确使用。
考虑这段代码:
root.after(0, MouseCounter().count())
它在功能上与以下内容相同:
result = MouseCounter().count()
root.after(0, None)
after
需要对函数的 引用 ,而不是实际的函数调用。您需要删除尾随的括号:
root.after(0, MouseCounter().count)
更好的方法是创建 MouseCounter
的实例并保存一个引用,这样它就不会被垃圾收集器回收:
counter = MouseCounter()
root.after(0, counter.count)
每次单击鼠标左键,self.LEFT_MB_Counter
都会递增,因此该值始终在变化。我希望 self.LEFT_MB_Counter
中的值显示在输入字段 self.left_MB_entry
中,但我无法实现。
如何让输入字段始终更新并显示 self.LEFT_MB_Counter
中的当前值?
from win32api import GetKeyState
import tkinter.ttk
import tkinter
class MainApplication:
"""Class that creates the widgets and window."""
def __init__(self, master):
"""Method that creates the class constructor."""
self.master = master
self.var = tkinter.IntVar(value=0)
self.left_MB_entry = self.Entry(self.var)
self.left_MB_entry.grid()
def Entry(self, text_var, justify="center"):
"""Method that defines a default entry field."""
entry = tkinter.ttk.Entry(self.master, textvariable=text_var, justify=justify)
return entry
class MouseCounter:
"""Class that counts mouse button clicks."""
def __init__(self):
"""Method that creates the class constructor."""
self.LEFT_MB = 0x01 # Virtual-key code from Microsoft for LEFT MButton
self.Old_State_LEFT_MB = GetKeyState(self.LEFT_MB) # LEFT MButton Down = -127 or -128, MButton Up = 0 or 1
self.LEFT_MB_Counter = 0 # Initialize to 0
def count(self):
# Following block of code monitors LEFT MButton
New_State_LEFT_MB = GetKeyState(self.LEFT_MB)
if New_State_LEFT_MB != self.Old_State_LEFT_MB: # Button state changed
self.Old_State_LEFT_MB = New_State_LEFT_MB
print(New_State_LEFT_MB)
if New_State_LEFT_MB < 0:
self.LEFT_MB_Counter += 1
print("Count:", self.LEFT_MB_Counter)
print('Left Button Pressed')
else:
print('Left Button Released')
root.after(1, self.count)
root = tkinter.Tk()
root.style = tkinter.ttk.Style()
# ('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
root.style.theme_use("clam")
APP = MainApplication(root) # Create object instance of the user interface
root.after(0, MouseCounter().count())
root.mainloop() # Display the user interface
一个选择是使 LEFT_MB_Counter
成为 IntVar
可以被 Entry
:
from multiprocessing import Process, Pipe
import time
from win32api import GetKeyState
import tkinter.ttk
import tkinter
class MainApplication(object):
"""Class that creates the widgets and window."""
def __init__(self, master):
"""Method that creates the class constructor."""
self.master = master
self.mc = MouseCounter(master)
root.after(0, self.mc.count)
self.left_MB_entry = self.Entry(self.mc.LEFT_MB_Counter)
self.left_MB_entry.grid()
def Entry(self, text_var, justify="center"):
"""Method that defines a default entry field."""
entry = tkinter.ttk.Entry(self.master, textvariable=text_var, justify=justify)
return entry
class MouseCounter:
"""Class that counts mouse button clicks."""
def __init__(self, master):
"""Method that creates the class constructor."""
self.master = master
self.LEFT_MB = 0x01 # Virtual-key code from Microsoft for LEFT MButton
self.Old_State_LEFT_MB = GetKeyState(self.LEFT_MB) # LEFT MButton Down = -127 or -128, MButton Up = 0 or 1
self.LEFT_MB_Counter = tkinter.IntVar(0) # Initialize to 0
def count(self):
# Following block of code monitors LEFT MButton
New_State_LEFT_MB = GetKeyState(self.LEFT_MB)
if New_State_LEFT_MB != self.Old_State_LEFT_MB: # Button state changed
self.Old_State_LEFT_MB = New_State_LEFT_MB
print(New_State_LEFT_MB)
if New_State_LEFT_MB < 0:
self.LEFT_MB_Counter.set(self.LEFT_MB_Counter.get() + 1)
print("Count:", self.LEFT_MB_Counter.get())
print('Left Button Pressed')
else:
print('Left Button Released')
self.master.after(1, self.count)
root = tkinter.Tk()
root.style = tkinter.ttk.Style()
root.style.theme_use("clam")
APP = MainApplication(root)
root.mainloop() # Display the user interface
您可以通过在 MouseCounter.count()
方法中更新 MainApplication
实例的名为 APP.var
的 IntVar
属性轻松地做到这一点。
这是您的代码的修改版本,展示了如何执行此操作:
from win32api import GetKeyState
import tkinter.ttk
import tkinter
class MainApplication:
"""Class that creates the widgets and window."""
def __init__(self, master):
"""Method that creates the class constructor."""
self.master = master
self.var = tkinter.IntVar(value=0)
self.left_MB_entry = self.Entry(self.var)
self.left_MB_entry.grid()
def Entry(self, text_var, justify="center"):
"""Method that defines a default entry field."""
entry = tkinter.ttk.Entry(self.master, textvariable=text_var, justify=justify)
return entry
class MouseCounter:
"""Class that counts mouse button clicks."""
def __init__(self, variable):
"""Method that creates the class constructor."""
self.LEFT_MB = 0x01 # Virtual-key code from Microsoft for LEFT MButton
self.Old_State_LEFT_MB = GetKeyState(self.LEFT_MB) # LEFT MButton Down = -127 or -128, MButton Up = 0 or 1
self.LEFT_MB_Counter = 0 # Initialize to 0
self.variable = variable
self.variable.set(self.LEFT_MB_Counter)
def count(self):
# Following block of code monitors LEFT MButton
New_State_LEFT_MB = GetKeyState(self.LEFT_MB)
if New_State_LEFT_MB != self.Old_State_LEFT_MB: # Button state changed
self.Old_State_LEFT_MB = New_State_LEFT_MB
print(New_State_LEFT_MB)
if New_State_LEFT_MB < 0:
self.LEFT_MB_Counter += 1
self.variable.set(self.LEFT_MB_Counter)
print("Count:", self.LEFT_MB_Counter)
print('Left Button Pressed')
else:
print('Left Button Released')
root.after(1, self.count)
root = tkinter.Tk()
root.style = tkinter.ttk.Style()
# ('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
root.style.theme_use("clam")
APP = MainApplication(root) # Create object instance of the user interface
mouse_counter = MouseCounter(APP.var) # Create an instance outside of mainloop.
root.after(0, mouse_counter.count)
root.mainloop() # Display the user interface
解决方案概述
问题的根源很简单,MouseCounter
的实例没有引用应用程序,因此不会影响应用程序中的任何内容。这不是 tkinter 独有的东西,它只是一个基本的 python 原则。要更改对象,您需要引用对象。
一旦您确定 MouseCounter
的实例引用了 MainApplication
的实例,问题就变得很容易解决了。
解决方案详情
您需要做的第一件事是将 var
与条目小部件正确关联。您的代码将其作为位置参数传递,这不是正确的方法。您需要将变量分配给 textvariable
属性:
self.var = tkinter.IntVar(value=0)
self.left_MB_entry = self.Entry(textvariable=self.var)
接下来,您需要确保 MouseCounter
能够传递主应用程序的实例:
class MouseCounter:
"""Class that counts mouse button clicks."""
def __init__(self, master):
self.master = master
...
创建实例时,传入APP
作为MainApplication
的实例:
APP = MainApplication(root)
mc = MouseCounter(APP)
root.after(0, mc.count)
接下来,您只需从您的计数器更新 var
:
def count(self):
...
if New_State_LEFT_MB < 0:
...
self.master.var.set(self.LEFT_MB_Counter)
...
注意:您对after
的工作原理有点误解。不影响代码,但是要用的话还是要正确使用。
考虑这段代码:
root.after(0, MouseCounter().count())
它在功能上与以下内容相同:
result = MouseCounter().count()
root.after(0, None)
after
需要对函数的 引用 ,而不是实际的函数调用。您需要删除尾随的括号:
root.after(0, MouseCounter().count)
更好的方法是创建 MouseCounter
的实例并保存一个引用,这样它就不会被垃圾收集器回收:
counter = MouseCounter()
root.after(0, counter.count)