tkinter输入字段自动更新

时间:2018-02-25 19:06:33

标签: python tkinter tkinter-entry

每按一次鼠标左键,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

3 个答案:

答案 0 :(得分:2)

一种选择是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 直接使用:

func main() {
    pairs := getPairs() //Returns an array of strings
    c := make(chan result)
    for _, product := range pairs {
        go getScore(product.Symbol, 1, c)
    }
    fmt.Println(len(c))
    time.Sleep(5000 * time.Millisecond)
    fmt.Println(len(c))
}

答案 1 :(得分:2)

您可以通过更新IntVar方法中APP.var实例的名为MainApplication的{​​{1}}属性轻松完成此操作。

以下是代码的修改版本,显示了如何执行此操作:

MouseCounter.count()

答案 2 :(得分:1)

解决方案概述

问题的根源只是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)