【问题标题】:Tkinter Disable several Entry with checkbuttonTkinter 使用复选按钮禁用多个条目
【发布时间】:2013-02-12 13:02:53
【问题描述】:

在 Python 2.7 中,我想通过一个检查按钮将“条目”小部件的状态变为正常/禁用。

借助这个问题Disable widget with checkbutton?,我可以用 1 个复选按钮和 1 个条目来完成

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-

import Tkinter as tk

root = tk.Tk()


class Principal(tk.Tk):
    def __init__(self, *args, **kwargs):
        self.foo = tk.StringVar()
        self.nac = tk.IntVar()

        self.ck1 = tk.Checkbutton(root, text='test',
            variable=self.nac, command=self.naccheck)
        self.ck1.pack()

        self.ent1 = tk.Entry(root, width=20, background='white',
            textvariable=self.foo, state='disabled')
        self.ent1.pack()

    def naccheck(self):
        print "check"
        if self.nac.get() == 0:
            self.ent1.configure(state='disabled')
        else:
            self.ent1.configure(state='normal')

app = Principal()
root.mainloop()

当我想要 2 对或更多对(检查按钮/条目)时,问题就来了。 在我的最终界面中,我可能有 20 个或更多这对,所以我想避免有 20 个或更多相同的“naccheck”方法。

我试过了:

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-

import Tkinter as tk

root = tk.Tk()


class Principal(tk.Tk):
    def __init__(self, *args, **kwargs):
        self.foo = tk.StringVar()
        self.nac = {}
        self.ent = {}

        self.ent["test"] = tk.Entry(root, width=20, background='white', textvariable=self.foo, state='disabled')
        self.ent["test"].pack()

        self.ent["image"] = tk.Entry(root, width=20, background='white', textvariable=self.foo, state='disabled')
        self.ent["image"].pack()

        self.nac["test"] = tk.IntVar()
        self.ck1 = tk.Checkbutton(root, text='test', variable=self.nac["test"], command=self.naccheck("test"))
        self.ck1.pack()

        self.nac["image"] = tk.IntVar()
        self.ck1 = tk.Checkbutton(root, text='image', variable=self.nac["image"], command=self.naccheck("image"))
        self.ck1.pack()


    def naccheck(self,item):
        print "check "+item
        print self.nac[item].get()
        if self.nac[item].get() == 0:
            self.ent[item].configure(state='disabled')
        else:
            self.ent[item].configure(state='normal')

app = Principal()
root.mainloop()

不幸的是,当我启动此代码时,会立即为每个检查按钮调用“naccheck”方法,而当我单击一个按钮时,则永远不会...

我做错了什么?

【问题讨论】:

  • 为什么不将所有Entrys 存储在一个数组中,然后在naccheck 中对它们运行for 循环?
  • 我的条目在一个数组中! 1个检查按钮必须“激活”相关条目。循环遍历 Entry 有什么好处?

标签: python checkbox tkinter tkinter-entry


【解决方案1】:

有很多方法可以解决这个问题。一种方法是将 entry 和 checkbutton 变量传递到您的检查函数中。首先创建条目小部件和变量。然后,创建检查按钮并将变量和条目传递给您的回调:

ent = tk.Entry(...)
var = tk.IntVar()
chk = tk.Checkbutton(..., command=lambda e=ent, v=var: self.naccheck(e,v))

注意 lambda 的使用,这是一种创建匿名函数的简单技术。这使您能够将参数传递给回调,而无需创建命名函数。另一种选择是使用functools.partial。毫无疑问,StackOverflow 上有几十个这样的例子,因为这是一个非常常见的问题。

接下来,您需要修改函数以接受参数:

def naccheck(self, entry, var):
    if var.get() == 0:
        entry.configure(state='disabled')
    else:
        entry.configure(state='normal')

【讨论】:

  • 谢谢! “lambda”函数可以解决问题:-)。当您定义“v”然后在“naccheck”调用中使用“c”时,只是命令中的拼写错误。
  • @ericc:感谢您让我知道错字;我修好了。
  • 经过测试,我为什么要使用“e”和“v”呢?似乎,无需修改我的代码,只需添加“lambda”, (command=lambda :self.naccheck("test")) 它也可以工作!
  • @ericc: lambda 很有用 如果 你想传入 v 和 c。正如您所建议的,还有其他解决问题的方法。如果您将对象存储在具有相同键的字典中,则传递键可以正常工作。
猜你喜欢
  • 2022-08-14
  • 1970-01-01
  • 1970-01-01
  • 2020-09-15
  • 2021-07-30
  • 1970-01-01
  • 2020-11-29
  • 1970-01-01
  • 2022-08-14
相关资源
最近更新 更多