Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在每个笔记本选项卡上获取checkbutton变量值Tkinter Python_Python_Arrays_List_Checkbox_Tkinter - Fatal编程技术网

在每个笔记本选项卡上获取checkbutton变量值Tkinter Python

在每个笔记本选项卡上获取checkbutton变量值Tkinter Python,python,arrays,list,checkbox,tkinter,Python,Arrays,List,Checkbox,Tkinter,在每个Tkinter笔记本选项卡上,都有一个复选按钮列表,变量保存到相应的v[](即cb.append(复选按钮(..,变量=v[x],..) 现在,我遇到了这个错误: File "/home/pass/OptionsInterface.py", line 27, in __init__ self.ntbk_render(f = self.f1, ntbkLabel="Options",cb = optsCb, msg = optMsg) File "/home/pass/OptionsInte

在每个Tkinter笔记本选项卡上,都有一个复选按钮列表,变量保存到相应的v[](即cb.append(复选按钮(..,变量=v[x],..)

现在,我遇到了这个错误:

File "/home/pass/OptionsInterface.py", line 27, in __init__
self.ntbk_render(f = self.f1, ntbkLabel="Options",cb = optsCb, msg = optMsg)
File "/home/pass/OptionsInterface.py", line 59, in ntbk_render
text = msg[x][1], command = self.cb_check(v, opt)))
File "/home/pass/OptionsInterface.py", line 46, in cb_check
opt[ix]=(v[ix].get())
IndexError: list assignment index out of range
我想错误就在这里。我不知道如何访问checkbutton变量的值

def cb_check(self, v = [], cb = [], opt = []):
    for ix in range(len(cb)):
      opt[ix]=(v[ix].get())
    print opt
以下是一些片段:

  def cb_check(self, v = [], cb = [], opt = []):
    for ix in range(len(cb)):
      opt[ix]=(v[ix].get())
    print opt

  def ntbk_render(self, f=None, ntbkLabel="", cb = [], msg = []):
    v = []
    opt = []
    msg = get_thug_args(word = ntbkLabel, argList = msg) #Allows to get the equivalent list (2d array) 
      #to serve as texts for their corresponding checkboxes

    for x in range(len(msg)):
      v.append(IntVar())
      off_value = 0
      on_value = 1
      cb.append(Checkbutton(f, variable = v[x], onvalue = on_value, offvalue = off_value,
        text = msg[x][1], command = self.cb_check(v, opt)))
      cb[x].grid(row=self.rowTracker + x, column=0, sticky='w')
      opt.append(off_value)
      cb[-1].deselect()

解决错误后,我想在按下底部的“确定”按钮后获得每个选项卡的checkbutton变量的所有值。任何有关如何操作的提示都会有所帮助!

好的,所以还有一点(…好的,可能会多一点…)这里比我预想的要多,但我会把它放在一个假设上,即你只需要从它那里拿走你需要的或找到有价值的东西

简单的回答是,当您的Checkbutton调用cb_check时,它传递的参数如下:

cb_check(self = self, v = v, cb = opt, opt = [])
我认为很明显,当我们这样写出来时,为什么会得到一个索引器:您使用opt列表的长度作为索引,用于在未提供opt时函数使用的空列表;换句话说,如果您有5个选项,它将尝试访问空列表[]上的索引[0…4](显然,一旦无法访问索引0,它就会停止)。您的函数不知道您要传递的东西称为v和opt:它只需要获取您提供的一些随机引用,并将它们按位置参数的顺序放置,然后依次填充关键字参数,然后用您告诉它使用的默认值填充其余关键字参数

半快速侧边:

在尝试修复错误时,如果我不知道出现了什么错误,我会先插入一个print语句,在它与虚线中涉及的所有引用断开之前插入,这通常会告诉您哪些引用不包含您认为它们包含的值。如果这看起来很好,那么我会越来越深入,检查任何查找/函数返回是否存在错误。例如:

def cb_check(self, v = [], cb = [], opt = []):
    for ix in range(len(cb)):
        print(ix, opt, v)  ## First check, for sanity’s sake

        print(v[ix])       ## Second Check if I still can’t figure it out, but
                           ## this is a lookup, not an assignment, so it
                           ## shouldn’t be the problem

        print(v[ix].get()) ## Third Check, again, not an assignment

        print(opt[ix])     ## “opt[ix]={something}” is an assignment, so this is
                           ## (logically) where it’s breaking. Here we’re only
                           ## doing a lookup, so we’ll get a normal IndexError
                           ## instead (it won’t say “assignment”)

        opt[ix]=(v[ix].get()) ##point in code where IndexError was raised
简单的修复方法是将Checkbutton命令更改为“lambda:self.cb_check(v,cb,opt)”或更明确地(因此我们可以进行健全性检查)“lambda:self.cb_check(v=v,cb=cb,opt=opt)。”(我将进一步提到,您可以将“lambda:”更改为“lambda v=v,cb=cb,opt=opt:”为了进一步确保您将永远引用相同的列表,但这应该是无关的,特别是因为我将在下面建议进行更改)

[剩下的部分是:第一部分-明确解释您的代码所做的事情并对其进行评论;第二部分-一种解决问题的替代方法。如上所述,上述内容解决了您的问题,因此剩下的部分只是一个改进练习]

关于你的推荐人姓名-

有一句古老的格言“代码的阅读频率远高于编写频率”,其中的一部分说:“显式优于隐式。[…]可读性很重要。”因此,不要害怕再多键入一点,以便更容易看到发生了什么(同样的逻辑适用于在上述解决方案中显式地将变量传递给cb_check)v可以是variscb可以是cbuttonsix(在我看来)会更好,因为ind或者干脆的索引f(在ntkb\U渲染中)应该是父级或者主级

进口-

看起来你要么在做明星(*)为tkinter导入,或者显式导入其中的一部分。我不鼓励您做这两件事,原因有两个。第一个原因与上面的原因相同:如果只需多敲几下键盘,就可以更容易地看到所有内容的来源,那么从长远来看,这是值得的。如果您以后需要通过代码查找每个tkinter小部件/Var/etc,然后简单地搜索“tk”比搜索“Frame”然后搜索“Checkbutton”然后搜索IntVar等等容易得多。其次,导入有时会发生冲突:例如,如果您这样做了

import time ## or from time import time, even
from datetime import time
生活可能会让你感到毛骨悚然。因此,将tkinter作为tk导入(例如)比目前的方式更好

cb_检查-

关于此函数,我将指出以下几点:

1) vcbopt都是函数正常工作所必需的;如果改为使用空列表引用,那么它将失败,除非您创建了0个复选按钮(因为在“for循环”中没有任何可迭代的内容);无论如何,这似乎不应该发生)。这意味着它们最好只是位置参数(没有默认值)。如果您以这种方式编写它们,函数会给您一个错误,说明您没有为其提供足够的信息,而不是半任意的“索引器”

2) 因为您为函数提供了它所需的所有信息,所以没有实际的理由(至少基于提供的代码)说明为什么函数需要成为某个对象的方法

3) 每次选择复选按钮时都会调用此函数,但会重新更新所有复选按钮(而不仅仅是选中的一个)的记录值(在opt

4) opt列表在技术上是多余的:您已经有了对所有IntVar(v)列表的引用,这些IntVar可以实时更新/维护,而无需您做任何事情;执行v[ix].get()基本上和执行opt[ix]一样简单:当您最终需要
import tkinter as tk ## tk now refers to the instance of the tkinter module that we imported
def ntbk_render(self, parent, word, argList):
    cbuttons=list() ## The use of “list()” here is purely personal preference; feel free to
                    ## continue with brackets
    msg = get_thug_args(word = word, argList=argList) ## returns a 2d array [ [{some value},
                                                      ## checkbutton text,…], …]

    for x,option in enumerate(msg):
        ## Each iteration automatically does x=current index, option=msg[current_index]
        variable = tk.IntVar()
        ## off and on values for Checkbuttons are 0 and 1 respectively by default, so it’s
        ## redundant at the moment to assign them
        chbutton=tk.Checkbutton(parent, variable=variable, text=option[1])
        chbutton.variable = variable ## rather than carrying the variable references around,
                                     ## I’m just going to tack them onto the checkbutton they
                                     ## belong to
        chbutton.grid(row = self.rowTracker + x, column=0, sticky=’w’) 
        chbutton.deselect()
        cbuttons.append(chbutton)
    self.rowTracker += len(msg) ## Updating the rowTracker
    return cbuttons

def get_options(self, cbuttons):
    ## I’m going to keep this new function fairly simple for clarity’s sake
    values=[]
    for chbutton in cbuttons:
        value=chbutton.variable.get() ## It is for this purpose that we made
                                      ## chbutton.variable=variable above
        values.append(value)
    return values