Python tkinter变量在另一个类中
Python 3.1,tkinter/ttk 我写了一些非常简单的东西,试图理解tkinter链接到小部件的变量如何存储在小部件的不同类中。代码如下 问题: 1为什么按下按钮不改变标签 我需要这么多的自我吗?每个方法中的变量是否可以无需自身管理。一开始 希望这个答案对其他tkinter新手来说是一个有用的学习练习Python tkinter变量在另一个类中,python,class,methods,tkinter,ttk,Python,Class,Methods,Tkinter,Ttk,Python 3.1,tkinter/ttk 我写了一些非常简单的东西,试图理解tkinter链接到小部件的变量如何存储在小部件的不同类中。代码如下 问题: 1为什么按下按钮不改变标签 我需要这么多的自我吗?每个方法中的变量是否可以无需自身管理。一开始 希望这个答案对其他tkinter新手来说是一个有用的学习练习 from tkinter import * from tkinter.ttk import * root = Tk() class Store: def __init__
from tkinter import *
from tkinter.ttk import *
root = Tk()
class Store:
def __init__(self):
self.v = IntVar()
self.v.set(0)
def set(self, v):
self.v.set(v)
class Main:
def __init__(self):
self.counter = 0
self.label = Label(root, textvariable = a.v)
self.label.pack()
self.button = Button(root, command = self.counter, text = '+1')
self.button.pack()
def counter(self):
self.counter = self.counter + 1
a.set(self.counter)
a = Store()
b = Main()
root.mainloop()
如果我是你,我会这样做:
import tkinter
root = tkinter.Tk()
var = tkinter.IntVar()
label = tkinter.Label(root, textvariable=var)
button = tkinter.Button(root, command=lambda: var.set(var.get() + 1), text='+1')
label.pack()
button.pack()
root.mainloop()
更新:
但是,如果您坚持对两个类执行此操作,其中第一个类只是一个毫无意义的接口,那么我会这样做:
import tkinter
class Store:
def __init__(self):
self.variable = tkinter.IntVar()
def add(self, value):
var = self.variable
var.set(var.get() + value)
return var.get()
class Main(tkinter.Tk):
def __init__(self, *args, **kwargs):
tkinter.Tk.__init__(self, *args, **kwargs)
var = Store()
self.label = tkinter.Label(self, textvariable=var.variable)
self.button = tkinter.Button(self, command=lambda: var.add(1), text='+1')
self.label.pack()
self.button.pack()
root = Main()
root.mainloop()
正如您可能注意到的,在您的版本中,我在两次使用了IntVar的get和set方法,我是通过我们制作的存储接口来实现的,因此您不需要使用像self.counter这样的新变量,因为我们实例化的变量正在存储数据
我使用的另一个东西是lambda表达式,而不是完整的函数定义,因为我们只想获取当前值,向其添加1,并将其存储为新值
在我的版本中,Main类是原始tkinter.Tk类的一个子类-这就是为什么我在Main的uu init uu方法中调用它的u init u方法。如果我是你,我会这样做:
import tkinter
root = tkinter.Tk()
var = tkinter.IntVar()
label = tkinter.Label(root, textvariable=var)
button = tkinter.Button(root, command=lambda: var.set(var.get() + 1), text='+1')
label.pack()
button.pack()
root.mainloop()
更新:
但是,如果您坚持对两个类执行此操作,其中第一个类只是一个毫无意义的接口,那么我会这样做:
import tkinter
class Store:
def __init__(self):
self.variable = tkinter.IntVar()
def add(self, value):
var = self.variable
var.set(var.get() + value)
return var.get()
class Main(tkinter.Tk):
def __init__(self, *args, **kwargs):
tkinter.Tk.__init__(self, *args, **kwargs)
var = Store()
self.label = tkinter.Label(self, textvariable=var.variable)
self.button = tkinter.Button(self, command=lambda: var.add(1), text='+1')
self.label.pack()
self.button.pack()
root = Main()
root.mainloop()
正如您可能注意到的,在您的版本中,我在两次使用了IntVar的get和set方法,我是通过我们制作的存储接口来实现的,因此您不需要使用像self.counter这样的新变量,因为我们实例化的变量正在存储数据
我使用的另一个东西是lambda表达式,而不是完整的函数定义,因为我们只想获取当前值,向其添加1,并将其存储为新值
在我的版本中,Main类是原始tkinter.Tk类的一个子类-这就是为什么我在Main的uu init uu方法中调用它的uu init uu方法。您的问题是既有一个方法,又有一个名为counter的变量。单击该按钮时,不会调用函数,因此不会设置变量。创建按钮时,tkinter认为self.counter是一个变量,而不是一个命令 这个特殊问题的解决方案是重命名函数或变量。然后它应该像你期望的那样工作 要回答关于过多self的问题:您需要使用self,以便python知道您所引用的对象应该在对象的特定实例中的任何地方都可用。所以,是的,如果你想引用函数之外的变量,你需要所有这些self 至于自我在定义方法时,这些也是必要的。当您执行object.method时,python将自动发送对该对象的引用,作为方法的第一个参数,以便该方法明确知道正在对哪个方法执行操作
如果您想更多地了解self的用法,这里有一个与self相关的特定问题:您的问题是您同时拥有一个名为counter的方法和变量。单击该按钮时,不会调用函数,因此不会设置变量。创建按钮时,tkinter认为self.counter是一个变量,而不是一个命令 这个特殊问题的解决方案是重命名函数或变量。然后它应该像你期望的那样工作 要回答关于过多self的问题:您需要使用self,以便python知道您所引用的对象应该在对象的特定实例中的任何地方都可用。所以,是的,如果你想引用函数之外的变量,你需要所有这些self 至于自我在定义方法时,这些也是必要的。当您执行object.method时,python将自动发送对该对象的引用,作为方法的第一个参数,以便该方法明确知道正在对哪个方法执行操作
如果你想更多地了解self的用法,这里有一个与self相关的特定问题:你的答案似乎没有回答被问到的问题。这个问题是专门针对多个类提出的。另外,你在没有任何解释的情况下编写了一些代码。如果有人只是在学习Tkinter,他们将很难理解您以不同的方式解决了这个问题。我修正了我的答案,尽管@BryanOakley我不认为我必须解释我的简短版本,因为它唯一的魔力是lambda表达式,它不是Tkinter,而是Python问题。无论如何,把我的代表还给我:当回答那些没有经验的人的问题时,解释是必要的,即使是简短的回答。还有什么别的
要知道问题的解决方案是或不是使用lambda,或是删除类,或是使用或不使用self,或是完全其他什么?他们对这些东西一无所知,所以当你给他们几行代码时,他们很可能会得出结论,类不应该与tkinter一起使用,即使这不是你想说的重点。实际上我解释了我的答案,添加了两个类的版本,而你仍然没有删除-1。。请向我解释一下,布莱恩·奥克利!我没有投反对票,但我不会投反对票,因为你没有回答被问到的问题。你说你不认为这个解释是必要的,我只是想解释一下为什么我认为它是必要的。你的回答似乎没有回答被问到的问题。这个问题是专门针对多个类提出的。另外,你在没有任何解释的情况下编写了一些代码。如果有人只是在学习Tkinter,他们将很难理解您以不同的方式解决了这个问题。我修正了我的答案,尽管@BryanOakley我不认为我必须解释我的简短版本,因为它唯一的魔力是lambda表达式,它不是Tkinter,而是Python问题。无论如何,把我的代表还给我:当回答那些没有经验的人的问题时,解释是必要的,即使是简短的回答。否则,他们怎么知道问题的解决方案是或不是使用lambda,或是删除类,或是使用或不使用self,或是完全其他什么?他们对这些东西一无所知,所以当你给他们几行代码时,他们很可能会得出结论,类不应该与tkinter一起使用,即使这不是你想说的重点。实际上我解释了我的答案,添加了两个类的版本,而你仍然没有删除-1。。请向我解释一下,布莱恩·奥克利!我没有投反对票,但我不会投反对票,因为你没有回答被问到的问题。你说你不认为这个解释是必要的,我只是想解释一下为什么我这么认为。我不认为这个答案对学习实用和干净的代码有帮助…@PeterVaro:这对我来说似乎是报复性的否决票,尽管我并不真的在乎声誉。您是对的,它对学习实用和干净的代码没有特别的帮助,但这并不是我们要问的问题。用户特别询问为什么在给定代码中按下按钮不起作用,我回答了这个问题。我认为说这不是一个有用的答案是不诚实的,而且可能会给OP留下这样的印象:我的答案在某种程度上是错误的,尽管它正确地说明了代码的实际问题。就像我的答案一样@Bryan Oakley!一旦你从我的答案中删除-1,我也会对你这样做。我也不在乎销售代表,但既然我的答案是两个版本都适用,而且都是正确、干净和实用的,我不知道你为什么首先给我-1,而不是在评论中给我一个警告,或者诸如此类的东西。@PeterVaro:我不讨价还价。我投有帮助的票,我不投没有帮助的票,我不会改变我的投票,这样其他人就会取消对我的反对票。我希望你也会这么做,这就是投票系统有用的原因。因为某人投了你的反对票而投反对票对任何人都没有帮助。@PeterVaro:你和我一样。不,你的答案不是。问题的一部分是为什么按下按钮不改变标签?而你从未接近解决这个问题。你也没有回答关于自我的问题。您确实提供了一个很好的替代解决方案,但这并不是所要求的。如果你这样做了,并且回答了被问到的实际问题,你肯定会得到我的支持票,尽管你出于恶意投票反对我。我不认为这个答案有助于学习实用和干净的代码…@PeterVaro:对我来说,这看起来像是报复性的反对票,尽管我并不真正关心声誉。您是对的,它对学习实用和干净的代码没有特别的帮助,但这并不是我们要问的问题。用户特别询问为什么在给定代码中按下按钮不起作用,我回答了这个问题。我认为说这不是一个有用的答案是不诚实的,而且可能会给OP留下这样的印象:我的答案在某种程度上是错误的,尽管它正确地说明了代码的实际问题。就像我的答案一样@Bryan Oakley!一旦你从我的答案中删除-1,我也会对你这样做。我也不在乎销售代表,但既然我的答案是两个版本都适用,而且都是正确、干净和实用的,我不知道你为什么首先给我-1,而不是在评论中给我一个警告,或者诸如此类的东西。@PeterVaro:我不讨价还价。我投有帮助的票,我投没有帮助的票,我不改变我的票,这样其他人就会删除n
对我投反对票。我希望你也会这么做,这就是投票系统有用的原因。因为某人投了你的反对票而投反对票对任何人都没有帮助。@PeterVaro:你和我一样。不,你的答案不是。问题的一部分是为什么按下按钮不改变标签?而你从未接近解决这个问题。你也没有回答关于自我的问题。您确实提供了一个很好的替代解决方案,但这并不是所要求的。如果你这样做了,并且回答了被问到的实际问题,你肯定会得到我的支持票,尽管你出于恶意投了我的反对票。