【问题标题】:How to access value from widgets if the widget was defined in a procedure如果小部件是在过程中定义的,如何从小部件中访问值
【发布时间】:2021-12-30 17:11:01
【问题描述】:

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

#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()

【问题讨论】:

    标签: python tkinter procedure


    【解决方案1】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-29
      • 2021-10-30
      • 2022-06-16
      • 2013-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多