奇怪的tk条目框行为

时间:2016-01-11 19:54:54

标签: python python-2.7 tkinter

我正在使用多个输入框,复选框等构建一个简单的GUI,并且在Tkinter.Entry类中遇到了一种非常特殊的行为,我想知道是否有其他人遇到过它和/或是否我只是做些傻事。

我创建了一个简单的类来包装每个Tkinter.Entry对象和接口。我想实现一种方法来改变每个框的宽度,所以我在类中添加了一个参数width。当我这样做时,我的所有盒子都变成了“链接”,当我输入一个盒子时,我输入每个盒子。在我实现这个功能之前,它工作正常,当我把它拿出来它再次工作。这是我的班级:

import Tkinter as tk

class EntryBox:
    def __init__(self, master, row, column, default_val="", width=20):
        self.val = tk.StringVar()
        self.default_val = default_val
        self.width = width
        # with the width parameter specified
        self.e = tk.Entry(master, text="cb_text", textvariable=self.val, width=self.width)
        # without the width parameter specified (defaults to a width of 20)
        # self.e = tk.Entry(master, text="cb_text", textvariable=self.val)
        self.e.grid(row=row, column=column, sticky=tk.E)
        self.e.insert(0, self.default_val)

    def get_val(self):
        return self.val.get()

    def activate(self):
        self.e.config(state=tk.NORMAL)

    def deactivate(self):
        self.e.config(state=tk.DISABLED)

    def focus(self):
        self.e.focus()

这是我的程序没有包含宽度参数:

Working Program

这是我的程序包含宽度参数:

Broken Program

如您所见,所有默认值都填写到每个框中,每当我编辑一个框时,我都会编辑所有默认值。

以下是我如何实例化每个对象(我不怀疑这是问题,但只是为了彻底):

import Tkinter as tk

ip_addr_box = EntryBox(root, 1, 1, default_val="192.168.201.116")
ip_addr_label = tk.Label(root, text="IP Address").grid(row=1, column=2, sticky=tk.W)
# set up the IP port entry box
ip_port_box = EntryBox(root, 2, 1, default_val="8000")
ip_port_label = tk.Label(root, text="IP port").grid(row=2, column=2, sticky=tk.W)
# set up the number of plot points scroll box
# set up the filename entry box
filename_box = EntryBox(root, 4, 1, default_val="log.xlsx")
filename_label = tk.Label(root, text="File Name").grid(row=4, column=2, sticky=tk.W)
# set up how long the test lasts
meas_time_box = EntryBox(root, 3, 4, default_val="5", width=10)
meas_time_label = tk.Label(root, text="Measurement Period")
meas_time_label.grid(row=3, column=5, columnspan=2, sticky=tk.W)
test_time_box = EntryBox(root, 4, 4, default_val="30", width=10)
test_time_label = tk.Label(root, text="Test Duration").grid(row=4, column=5, columnspan=2, sticky=tk.W)

我的猜测是,这是Tkinter中的一个奇怪的错误或与namespaces有关的一些我不太了解的错误。

编辑:我更新了类代码,以指定我不包含width参数的方式。在调用tk.Entry时,我甚至不把它作为命名参数包含在内。

2 个答案:

答案 0 :(得分:1)

删除属性text='cb_text'。我不知道你的想法,但text只是textvariable的缩写,因此使用它与做Entry(..., textvariable='cb_text', textvariable=self.var相同,... )。

显然,tkinter Entry小部件处理命名参数的方法存在错误,并且在添加width参数时会触发该错误。每个条目小部件最终都将textvariable属性设置为"cb_text",这意味着它们共享相同的存储空间。

答案 1 :(得分:-1)

继承Tkinter Entry类效果很好。我稍微操纵了你的代码。

import Tkinter as tk

class EntryBox(tk.Entry):
    def __init__(self, master, row, column, default_val="", width=20):
        tk.Entry.__init__(self, master, text="cb_text")
        self.val = tk.StringVar()
        self.default_val = default_val
        self.width = width
        # with the width parameter specified
        # self.e = tk.Entry(master, text="cb_text", textvariable=self.val, width=self.width)
        # without the width parameter specified (defaults to a width of 20)
        # self.e = tk.Entry(master, text="cb_text", textvariable=self.val)
        # self.e.grid(row=row, column=column, sticky=tk.E)
        self.config(textvariable=self.val, width=self.width)
        self.insert(0, self.default_val)
        self.grid(row=row, column=column, sticky=tk.E)


    def get_val(self):
        return self.val.get()

    def activate(self):
        self.e.config(state=tk.NORMAL)

    def deactivate(self):
        self.e.config(state=tk.DISABLED)

    def focus(self):
        self.e.focus()

很遗憾,我没有足够的代表点直接发表评论。