Coding a general function to: Disable a tkinter widget with a checkbutton

huangapple go评论78阅读模式
英文:

Coding a general function to: Disable a tkinter widget with a checkbutton

问题

我正在尝试编写一个函数,根据复选框的值来禁用tkinter程序中的一个小部件。我希望这个函数是通用的,也就是说,我可以传递小部件和关联的检查变量给它,它将禁用小部件(如果变量以正确的方式被选中)。

以下是我代码的抽象版本:

import tkinter
class App:
    def __init__(self, root):
        widg = tkinter.Scale(root, from_=0, to=100)
        checkvar = tkinter.IntVar()
        checker = tkinter.Checkbutton(root, variable=checkvar, command=self.check(widg, checkvar))
        widg.grid()
        checker.grid()

        widg.configure(state=tkinter.DISABLED)
        widg.configure(state=tkinter.NORMAL)

    def check(self, widget, var):
        if var.get() == 1:
            widget.configure(state=tkinter.DISABLED)
        elif var.get() == 0:
            widget.configure(state=tkinter.NORMAL)

m = tkinter.Tk()
f = App(m)

它的预期功能是,单击复选框会触发回调函数check,并传递小部件和检查变量的参数。然后它将评估小部件应该是开启还是关闭,并相应地更改其状态。虽然没有错误,但状态没有改变。我在这里漏掉了什么?

谢谢。

英文:

I'm trying to write a function to disable a widget in a tkinter program depending on the value of a checkbutton. I want this function to be general: That is, I can pass it the widget and associated check variable and it will disable the widget (if the variable is checked the right way).

Here is an abstracted version of my code

import tkinter
class App:
	def __init__(self,root):
		widg = tkinter.Scale(root,from_=0,to=100)
		checkvar  = tkinter.IntVar()
		checker = tkinter.Checkbutton(root,variable=checkvar,command=self.check(var,checkvar))
		widg.grid()
		checker.grid()

		widg.configure(state=tkinter.DISABLED)
		widg.configure(state=tkinter.NORMAL)

	def check(self,widget,var):
		if var.get()==1:
			widget.configure(state=tkinter.DISABLED)
		elif var.get()==0:
			widget.configure(state=tkinter.NORMAL)


m = tkinter.Tk()
f=App(m)

It is intended to function such that clicking the checkbutton triggers the callback - check - with the parameters of the widget and the check variable. Then it will evaluate whether the widget should be on or off and change its state accordingly. There are no errors but the state doesn't change. What am I missing here?

Thanks

答案1

得分: 2

以下是您提供的内容的中文翻译:

命令参数只需取未调用的函数,因此向它传递参数需要一些变通方法。

因此,它期望 self.check 而不是 self.check(),因为小部件将在稍后调用该函数。

我发现使用 partial 是传递参数的一种变通方法。

import tkinter
from functools import partial

class App:
    def __init__(self, root):
        widg = tkinter.Scale(root, from_=0, to=100)
        checkvar = tkinter.IntVar()
        checker = tkinter.Checkbutton(root, variable=checkvar, command=partial(self.check, widg, checkvar))
        widg.grid()
        checker.grid()

        widg.configure(state=tkinter.DISABLED)
        widg.configure(state=tkinter.NORMAL)

    def check(self, widget, var):
        if var.get() == 1:
            widget.configure(state=tkinter.DISABLED)
        elif var.get() == 0:
            widget.configure(state=tkinter.NORMAL)

m = tkinter.Tk()
f = App(m)
m.mainloop()

请注意,我已经按您的要求只提供了代码的翻译部分。如果您有任何其他需要,请随时告诉我。

英文:

The command argument simply takes the uncalled function so passing arguments to it takes some workaround.

So it expects self.check rather than self.check() since the widget will call the function later.

I've found that using partial is a workaround for passing the arguments.

import tkinter
from functools import partial

class App:
    def __init__(self,root):
        widg = tkinter.Scale(root,from_=0,to=100)
        checkvar  = tkinter.IntVar()
        checker = tkinter.Checkbutton(root,variable=checkvar,command=partial(self.check, widg, checkvar))
        widg.grid()
        checker.grid()

        widg.configure(state=tkinter.DISABLED)
        widg.configure(state=tkinter.NORMAL)

    def check(self,widget,var):
        if var.get()==1:
            widget.configure(state=tkinter.DISABLED)
        elif var.get()==0:
            widget.configure(state=tkinter.NORMAL)


m = tkinter.Tk()
f=App(m)
m.mainloop()

答案2

得分: 0

Credit to my friend JB for helping me with this.

正如用户Axe319建议的,问题仅在于tkinter不希望传递任何参数。可以通过使用lambda函数来解决这个问题。定义检查器变量的那一行,在我的原始帖子的第8行,可以重写如下:

self.checker = tkinter.Checkbutton(root, variable=checkvar, command=lambda:self.check(self.widg, checkvar))

这样它将按预期工作。

英文:

Credit to my friend JB for helping me with this.

As user Axe319 suggested, the problem is just that tkinter doesn't expect to pass any parameters. It is possible to work around this by using a lambda function. The line that defines the checker variable, in my original post line 8, can be rewritten as such:

self.checker = tkinter.Checkbutton(root,variable=checkvar,command=lambda:self.check(self.widg,checkvar))

and it will work as intended.

huangapple
  • 本文由 发表于 2020年1月3日 23:44:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/59581410.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定