Tkinter-从动态生成的小部件中检索值-回调

时间:2019-06-20 15:06:14

标签: python python-3.x tkinter tk

我正在尝试通过Tkinter创建一个GUI,该GUI将根据一些用户输入来计算产量。根据用户选择的系统数量,我弹出了针对逆变器类型的选项菜单数量,并且针对每个字符串,每个逆变器字符串和每个系统的逆变器弹出了输入小部件数量。如果用户选择2个系统,请参见图片的示例。

我正在使用回调函数来实时获取用户选择的数量的系统,以动态生成上面讨论的逆变器/模块小部件。

我的问题是我无法从这些小部件中检索值。我的尝试显示在天气计算功能中。

我认为问题是因为我在回调函数中生成了小部件/变量。但是,我还无法找到一种基于回调函数外部的用户输入来动态生成小部件数量的方法。

在此方面提供的任何帮助将不胜感激!

  class Window:  

# Define User Inputs:  
    def __init__(self, master):  
        master.title('Production Analysis Tool')  

 # EQUIPMENT PARAMETERS         

    # callback function to create entry boxes based on number of systems  
        def callback(*args):  
            self.system_size = int(self.system_size_raw.get())  

        # Modules per String  
            self.L3 = Label(root, text = "Number of Modules Per String").grid(row=20, column=1, sticky=E)  
            self.modules_string_raw = IntVar(root)  
            modules_per_string =[]  
            for i in range(self.system_size):  
                self.label = Label(root, text = "System {}".format(i+1)).grid(row=21+i, column=1, sticky=E)  
                self.widget = Entry(root).grid(row=21+i, column=2, sticky=W)  
                modules_per_string.append(self.widget)  

    # Number of Systems  
        self.L1 = Label(root, text = "Number of Systems").grid(row=1, column=1, sticky=E)  
        self.system_size_raw = IntVar(root)  
        choices = [1,2,3,4,5,6,7,8,9,10]  
        self.popupMenu2 = OptionMenu(root, self.system_size_raw, *choices).grid(row=1, column=2, sticky=W)  
        self.system_size_raw.trace("w", callback)  


#Calculation Function  

    def weather_calculation(self):     

    # Get Values from User Input  

        self.mod_strings = np.float(self.modules_string_raw.get())  

root = Tk()  
root.configure()  
window = Window(root)  
root.mainloop()

Example GUI

2 个答案:

答案 0 :(得分:1)

您需要做的就是在列表中保存对Entry小部件的引用。然后,您可以遍历该列表以获取每个小部件的值。

看来您已经将小部件保存到列表变量modules_per_string中。您需要做的就是使全局或对象属性(而不是局部变量)成为全局属性,以便其他函数可以引用它。

答案 1 :(得分:0)

如布赖恩·奥克利(Bryan Oakley)所说,为小部件创建列表,以将条目的每个对象和标签存储在两个列表中。

例如:

import tkinter as tk
class Demo:
    def __init__(self):
        self.root = tk.Tk()
        self.root.geometry("600x600")
        systems_label = tk.Label(self.root, text="No Of Systems:")
        systems_label.place(x=100, y=20)

        no_Of_System_Ent = tk.Entry(self.root, width=15)
        no_Of_System_Ent.place(x=200, y=20)

        submit_Button = tk.Button(self.root, text="Submit", command=lambda: self.process(no_Of_System_Ent.get()))
        submit_Button.place(x=350,y=20)

    def display(self,sys_len): 
        for i in range(sys_len):
              buffer = self.obj_of_entries[i].get()
              print(buffer)

    def delete(self,sys_len):
         for i in range(sys_len):
              self.obj_of_entries[i].destroy()
              self.obj_of_labels[i].destroy()

    def process(self,length_sys):
         self.obj_of_entries = []
         self.obj_of_labels = []
         y_pos = 80
         for i in range(int(length_sys)):
              #Adding objects of label in list 'obj_of_labels'
              self.obj_of_labels.append(tk.Label(self.root,text="System "+str(i)))
              self.obj_of_labels[len(self.obj_of_labels)-1].place(x=100,y=y_pos)

              #Adding objects of entry in list 'obj_of_entries'
              self.obj_of_entries.append(tk.Entry(self.root,width=15))
              self.obj_of_entries[len(self.obj_of_entries)-1].place(x=200,y=y_pos)

              #Increments Y by 50
              y_pos = y_pos + 50

              self.delete_Button = tk.Button(self.root, text="Delete All", command=lambda: self.delete(int(length_sys)))
              self.delete_Button.place(x=200,y=400)

              self.print_Button = tk.Button(self.root, text="Print All", command=lambda: self.display(int(length_sys)))
              self.print_Button.place(x=350,y=400) 

ob=Demo()

在此示例中:

我在init函数中创建了一个条目和按钮,以使用户不使用任何系统。

def __init__(self):
    self.root = tk.Tk()
    self.root.geometry("600x600")

    systems_label = tk.Label(self.root, text="No Of Systems:")
    systems_label.place(x=100, y=20)

    no_Of_System_Ent = tk.Entry(self.root, width=15)
    no_Of_System_Ent.place(x=200, y=20)

    submit_Button = tk.Button(self.root, text="Submit", command=lambda: self.process(no_Of_System_Ent.get()))
    submit_Button.place(x=350,y=20)

点击提交按钮后,将进入处理功能。

Ps:length_sys是系统数。

def process(self,length_sys):
    self.obj_of_entries = []
    self.obj_of_labels = []
    y_pos = 80
    for i in range(int(length_sys)):
        #Adding objects of label in list 'obj_of_labels'
        self.obj_of_labels.append(tk.Label(self.root,text="System "+str(i)))
        self.obj_of_labels[len(self.obj_of_labels)-1].place(x=100,y=y_pos)

        #Adding objects of entry in list 'obj_of_entries'
        self.obj_of_entries.append(tk.Entry(self.root,width=15))
        self.obj_of_entries[len(self.obj_of_entries)-1].place(x=200,y=y_pos)

        #Increments Y by 50
        y_pos = y_pos + 50

        self.delete_Button = tk.Button(self.root, text="Delete All", command=lambda: self.delete(int(length_sys)))
        self.delete_Button.place(x=200,y=400)

它将把条目和标签obj附加在其各自的列表中,并将当前obj放置在GUI窗口中。 最后,它将使y轴增加80,以便下一个标签和条目下降到上一个标签。

如果用户单击“全部删除”按钮,则将删除所有条目和标签的所有列表obj。

Ps:sys_len是系统编号。

def delete(self,sys_len):
    for i in range(sys_len):
        self.obj_of_entries[i].destroy()
        self.obj_of_labels[i].destroy()

要查看内容,请使用此代码:

(它将在Python shell中打印,因此您可以查看数据是否正确。)

def display(self,sys_len): 
    for i in range(sys_len):
        buffer = self.obj_of_entries[i].get()
        print(buffer)

我想我解决了疑问。 iao!