如果小部件是在过程中定义的,如何从小部件访问值

How to access value from widgets if the widget was defined in a procedure

我正在测试 tkinter 并尝试对过程中创建的 GUI 的值进行计算。如果 GUI 创建不是在一个过程中,它工作正常,但如果小部件是在一个过程中创建的,则无法识别小部件,即使 GUI 过程在另一个 functions/procedures 之前定义并在之后调用。这是不可能的还是我做错了什么?

#TKinter Threading Test

#Importing all relevant tkinter modules
import tkinter as tk
from tkinter import ttk


#Importing threading
from threading import Thread

#Importing queues
import queue

def take_value():
    #Place the input_widget value into the queue
    temp = input_widget.get()
    print(temp)
    #Temporarily pause the entry of new variables
    input_widget.config(state = "disabled")
    output_widget.config(state = "disabled")
    queue_input.put(temp)

def place_value():
    #Check if there is a value in the output queue at all
    if queue_output.empty():
        #print("Output queue is empty")
        temp = "Nothing"
    else:
        temp = queue_output.get()
        #Place the value onto the label
        output_widget.config(text = temp)
        #Re-activate the widgets
        input_widget.config(state = "normal")
        output_widget.config(state = "normal")
    thrdng_root.after(100, place_value)

def calculation_process():
    #Check if there is a value in the input queue at all
    while True:
        if queue_input.empty():
            #print("Input queue is empty")
            temp = "Nothing"
        else:
            temp = queue_input.get()
            new_value = str(float(temp) + 1)
            print(new_value)
            queue_output.put(new_value)

def create_GUI():
    #Creating window
    thrdng_root = tk.Tk()
    thrdng_root.geometry("900x900")

    #Creating a queue for values going into the calculation
    queue_input = queue.Queue()
    #Creating a queue for values coming out
    queue_output = queue.Queue()

    #Creating grid columns
    thrdng_root.columnconfigure(0, weight = 3)
    thrdng_root.columnconfigure(1, weight = 7)
    thrdng_root.columnconfigure(2, weight = 3)

    #Creating grid rows
    thrdng_root.rowconfigure(0, weight = 5)
    thrdng_root.rowconfigure(1, weight = 1)
    thrdng_root.rowconfigure(2, weight = 5)
    thrdng_root.rowconfigure(3, weight = 5)
    thrdng_root.rowconfigure(4, weight = 5)

    #Creating entry widget for the user to input a value
    input_widget = ttk.Entry(thrdng_root)
    input_widget.grid(column = 1, row = 0)

    #Creating the output widget
    output_widget = ttk.Label(thrdng_root, background = "#FFFFFF")
    output_widget.grid(column = 1, row = 2)

    place_value()

    #Creating the button that submits the data to the loop
    submit_widget = ttk.Button(thrdng_root, text = "Calculate", command = take_value)
    submit_widget.grid(column = 1, row = 3)

    #Setting the function as a thread
    calc_thread = Thread(target = calculation_process)

    #Starting the thread so that the two indefinite loops can go on without blocking each other
    calc_thread.start()

    #Starting the indefinite GUI loop
    thrdng_root.mainloop()

create_GUI()

这对于 tkinter 小部件和任何其他 python 对象没有什么不同。您需要保存对小部件的引用,并提供一种访问该引用的方法。这通常通过以下方法之一完成:

  1. 如果您不使用 类
  2. ,请将参考保存为全局参考
  3. 如果您使用 类
  4. ,请将引用保存为实例变量
  5. 将引用传递给需要它的函数。

由于您没有使用 类,因此排除了 #2。最简单的解决方案是使用全局变量。对于您希望能够在创建位置以外的函数中访问的每个小部件,您应该将其声明为全局的。

例如,如果 input_widget 是您需要在多个地方使用的小部件之一,请在定义它的函数中将其声明为全局 .

def create_GUI():
    global input_widget
    ...
    input_widget = ttk.Entry(thrdng_root)'
    ...