【问题标题】:Use variable outside its function在其函数之外使用变量
【发布时间】:2018-05-27 00:46:44
【问题描述】:

我正在使用一个函数,它允许用户从列表中选择一个项目并将索引存储到一个变量中。我想在函数之外使用该变量,但它不起作用。

这是我目前所拥有的。 (仅供参考:mylist 部分代码未显示)

class FirstWindow(Frame):
    selection_index = '0'
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)

         num_lines_lights = 4
         scrollbar = Scrollbar(self)
         #scrollbar.pack(side=RIGHT, fill=Y)
         scrollbar.place(x=55,y=200)
         #scrollbar.place(x=25, y=50)
         mylist = Listbox(self, yscrollcommand = scrollbar.set)
         for line in range(num_lines_lights):
             mylist.insert(END, "Light " + str(line))
         mylist.pack(side = LEFT, fill = BOTH)
         mylist.place(x=70,y=200)
         scrollbar.config(command = mylist.yview)

        def select_item(event):
            global selection_index
            widget = event.widget
            selection_index = (widget.curselection()[0])
            value = widget.get(index)
            print("Inside function %s " % selection_index) #works fine

        mylist.bind('<<ListboxSelect>>', select_item)

        print("This is return %s " % selection_index) #NOT WORKING

这是我收到的错误:

print("This is return %s " % selection_index)
NameError: name 'selection_index' is not defined

【问题讨论】:

标签: python python-3.x tkinter


【解决方案1】:

因为global关键字,它限制了变量的范围。您可以使用self 代替全局变量并在def __init__() 中定义变量

def __init__(self, parent, controller):
    self.selection_index = '0'

现在,不要使用selection_index,而是使用self.selection_index

【讨论】:

    【解决方案2】:

    您不应该为此尝试使用global。使用类的主要原因之一是它可以以一种易于访问的方式保存相关对象。

    您可以将selection_index 设为FirstWindow 的实例属性。像这样:

    class FirstWindow(Frame):
        def __init__(self, parent, controller):
            Frame.__init__(self, parent)
            self.selection_index = '0'
    
            def select_item(event):
                widget = event.widget
                selection_index = (widget.curselection()[0])
                value = widget.get(index)
                print("Inside function %s " % self.selection_index)
    
            mylist.bind('<<ListboxSelect>>', select_item)
    
            print("This is return %s " % self.selection_index)
    

    当然,这只会打印This is return 0,因为select_item 还没有机会运行。


    这是一个基于您发布的新代码的可运行示例,它仍然不是 MCVE:我必须添加额外的东西才能使其可运行。顺便说一句,您不应该在一个容器小部件中混合使用不同的布局方法(打包、放置、网格),因为它们不能相互协作。

    我添加了一个额外的按钮来证明self.selection_index 在整个FirstWindow 中都可用。

    from tkinter import *
    
    class FirstWindow(Frame):
        def __init__(self, parent, controller):
            Frame.__init__(self, parent)
            self.selection_index = '-1'
    
            num_lines_lights = 4
            scrollbar = Scrollbar(self)
            scrollbar.pack(side=RIGHT, fill=Y)
            mylist = Listbox(self, yscrollcommand=scrollbar.set)
            for line in range(num_lines_lights):
                mylist.insert(END, "Light " + str(line))
            mylist.pack(side=LEFT, fill=BOTH)
            scrollbar.config(command = mylist.yview)
    
            def select_item(event):
                widget = event.widget
                self.selection_index = (widget.curselection()[0])
                value = widget.get(self.selection_index)
                print("Inside function %s: %s" % (self.selection_index, value))
    
            mylist.bind('<<ListboxSelect>>', select_item)
            print("This is return %s " % self.selection_index)
    
            # A button to print the current selection_index
            Button(parent, text='Show index', command=self.show_index).pack()
    
        def show_index(self):
            print(self.selection_index)
    
    root = Tk()
    win = FirstWindow(root, root)
    win.pack()
    root.mainloop()
    

    顺便说一句,最好不要使用from tkinter import *。相反,使用

    import tkinter as tk
    

    然后你执行root = tk.Tk()scrollbar = tk.Scrollbar(self) 等操作。这使代码更易于阅读,因为它清楚地表明了导入名称的来源,并且它阻止 Tkinter 将 130 多个名称转储到您的全局命名空间,这可能导致名称冲突。

    【讨论】:

    • 我认为意图可能是在值更改时打印,而不是在创建类时打印。换句话说,它总是在最后一行打印 0
    • @lrma 然后删除最后的打印,如果不需要的话
    • 我正在使用该打印语句来尝试验证输出。我希望它打印选择的值。我更新了代码
    • 我想将选择保存到一个变量中以供以后使用,但我不知道该怎么做。 print 语句仅用于验证输出,但显然不正确
    • @Irma 你可以稍后在课堂上的任何地方使用self.selection_index
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-21
    • 2019-01-07
    • 1970-01-01
    相关资源
    最近更新 更多