列表中的Tkinter Entry Widgets都保存相同的数据

时间:2017-08-02 14:37:02

标签: python python-3.x tkinter

我有一个名为from sh import gunzip gunzip('/tmp/file1.gz') 的函数,它位于我的tkinter GUI中间。我希望用户选择一个数字并创建他们选择的输入框数量。我想出了如何使用for循环并将每个输入框放入列表中。但是,无论何时写入内容,都会在所有条目小部件之间保存相同的数据。

我不想显示我的所有代码,但可以显示正在发生的所有功能。

display_change

这就是我输入内容时的样子:

我打的所有内容都是' abcd'一次,但它进入了所有条目

4 个答案:

答案 0 :(得分:3)

当您查看tkinters文档中的所有可用config选项时,字段text不是其中之一。很可能因为textvariable是条目字段的可用参数,因此tkinter将text视为textvariable的缩写。因此,正在发生的事情是,所有的Entry字段都被分配了相同的文本变量,当一个条目更改该变量时,所有这些变量都使用该变量中的新字符串进行更新。

编写for循环的正确方法如下:

for i in range(nodes):
    if nodes  <= 4:
        labels.append(tk.Label(area, text="Part {}".format(i+1)))
        labels[i].place(x=10+(120*i), y=55)
        entries.append(tk.Entry(area))
        entries[i].insert(0, "Change Ip") # adds text directly to an entry field
        entries[i].place(x=10 + (120 * i), y=80, width=100)
    else:
        labels.append(tk.Label(area, text="Node {}".format(i+1)))
        labels[i].place(x=10 + (120 * i), y=105)
        entries.append(tk.Entry(area)
        entries[i].insert(0, "Change Ip")
        entries[i].place(x=10 + (120 * i), y=160, width=100)

答案 1 :(得分:0)

我完全不理解它,但text关键字参数将所有条目与相同的字符串变量相关联,然后存储并同时更新所有内容。

您可以使用&#34; insert&#34;而不是传递text关键字。实例化后的条目方法,用于在条目中设置文本。

Tkinter没有世界上最好的文档,因此我不完全确定text关键字的用途。会继续调查。这是一个没有出现问题行为的MVCE:

import tkinter as tk
from tkinter.ttk import Frame, Button
labels = []
entries = []

def display_change(self, area, nodes):
    """Here is where the display is changed so what the user choose is correctly seen"""

    lower_label = tk.Label(area, text="Enter the value of each part")
    lower_label.grid(row=2, column=0, sticky=tk.N + tk.W)

    global labels, entries
    for label in labels:
        label.destroy()
    for entry in entries:
        entry.destroy()
    labels = []
    entries = []

    # This loop creates the correct number of entry box's and labels. Each entry is stored separately
    for i in range(nodes):
        if nodes <= 4:
            labels.append(tk.Label(area, text="Part "+str(i+1)))
            labels[i].place(x=10+(120*i), y=55)
            entries.append(tk.Entry(area))
            entries[i].insert(0, "Change IP")
            entries[i].place(x=10 + (120 * i), y=80, width=100)

root = tk.Tk()

display_change(None, root, 4)

root.mainloop()

答案 2 :(得分:0)

问题是因为Entry窗口小部件没有text选项,这就是他们显示的初始值不是"Change Ip"的原因。 Entry窗口小部件有一个textvariable选项,必须将其设置为StringVar才能让您以后使用var.get()调用从中检索当前文本。< / p>

以下是代码的可运行版本,其中显示了如何在display_change()方法中执行此操作的示例。添加了一个名为textvars的新全局列表,用于保存每个StringVar窗口小部件的Entry。您可以使用其中的条目获取每个对应的Entry中的当前文本。

import tkinter as tk
from tkinter.ttk import Frame, Button

labels = []
entries = []
textvars = []

class Application(Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.mainFrame()

    def mainFrame(self):
        self.master.title("Tinc VM Setup")
        self.pack(fill=tk.BOTH, expand=True)
        self.columnconfigure(1, weight=1)
        self.columnconfigure(3, pad=7)
        self.rowconfigure(3, weight=1)
        self.rowconfigure(5, pad=7)
        lbl = tk.Label(self, text="Follow the instructions on each page",
                       bg="snow2")
        lbl.grid(sticky=tk.W, pady=4, padx=5)

        area = tk.Frame(self, bg="white")
        area.grid(row=1, column=0, columnspan=3, rowspan=4,
              padx=5, sticky=tk.E + tk.W + tk.S + tk.N)

        # ----------Inside White Box ---------------------
        lbl = tk.Label(area, text="Select the number of parts to create:")
        lbl.grid(row=1, column=0)

        choices = {0, 3, 4, 5, 6, 7, 8, 9, 10}

        node_count = tk.IntVar()
        node_count.set(0)
        node_select = tk.OptionMenu(area, node_count, *choices,
            command=lambda x: self.display_change(area, node_count.get()))
        node_select.grid(row=1, column=2)

        # -----------Outside Part-------------------------
        abtn = Button(self, text="Thing 1")
        abtn.grid(row=1, column=3, sticky=tk.W)
        cbtn = Button(self, text="Thing 2")
        cbtn.grid(row=2, column=3, pady=4, sticky=tk.W)

        abtn2 = Button(self, text="Thing 3")
        abtn2.grid(row=3, column=3, sticky=tk.W + tk.N)

        cbtn2 = Button(self, text="Thing 4")
        cbtn2.grid(row=3, column=3, pady=28, sticky=tk.W + tk.N)

        hbtn = Button(self, text="Exit")
        hbtn.grid(row=5, column=2, sticky=tk.W)

        sbtn = Button(self, text="Save")
        sbtn.grid(row=5, column=3, pady=3, sticky=tk.W)

        sbtn = Button(self, text="Help")
        sbtn.grid(row=5, column=0, sticky=tk.W)

    def display_change(self, area, nodes):
        """Here is where the display is changed so what the user choose is
           correctly displayed.
        """
        lower_label = tk.Label(area, text="Enter the value of each part")
        lower_label.grid(row=2, column=0, sticky=tk.N + tk.W)

        global labels, entries, textvars
        for label in labels:
            label.destroy()
        for entry in entries:
            entry.destroy()
        labels = []
        entries = []
        textvars = []

        # This loop creates the correct number of entry box's and labels.
        # Each entry is stored separately
        for i in range(nodes):
            if nodes <= 4:
                labels.append(tk.Label(area, text="Part "+str(i+1)))
                labels[-1].place(x=10+(120*i), y=55)
                textvars.append(tk.StringVar())
                textvars[-1].set("Change Ip")
                entries.append(tk.Entry(area, textvariable=textvars[-1]))
                entries[-1].place(x=10 + (120 * i), y=80, width=100)
            else:
                labels.append(tk.Label(area, text="Node " + str(i + 1)))
                labels[-1].place(x=10 + (120 * i), y=105)
                textvars.append(tk.StringVar())
                textvars[-1].set("Change Ip")
                entries.append(tk.Entry(area, textvariable=textvars[-1]))
                entries[-1].place(x=10 + (120 * i), y=160, width=100)

if __name__ == "__main__":
    root = tk.Tk()

    """Calculate center of screen so popup is center"""
    w = 650
    h = 400

    ws = root.winfo_screenwidth()
    hs = root.winfo_screenheight()

    x = (ws / 2) - (w / 2)
    y = (hs / 2) - (h / 2)
    root.geometry('%dx%d+%d+%d' % (w, h, x, y))

    # This line prevents the user from changing the size of the window
    root.resizable(width=False, height=False)

    app = Application(root)
    root.mainloop()

答案 3 :(得分:0)

变量应该通过textvariable在Entry中指定并在开头使用StringVar()定义,请检查以下代码

from Tkinter import *
import ttk


root = Tk()
root.title("GUI titile")
root.geometry("200x100")


variable1 = StringVar()
variable2 = StringVar()

entry1 = Entry(root,textvariable=variable1)
entry1.pack()

entry2 = Entry(root,textvariable=variable2)
entry2.pack()

root.mainloop()

GUI输出图像:

GUI output image

注意:导入因python版本

而异