NameError: global name is not defined' creatin

2019-09-02 06:27发布

问题:

im trying to create a program that will load a file (called lines.txt), add lines to it and will remove them, im using tkinter as a gui. i cannot however finish the add_line section as it always returns "NameError: global name is not defined' creating error when it has been defined.", it is defined on line 29 as listbox = Listbox(root), the section it is failing at is in def Add_Barcode(self): in def Add(self): on line 95. listbox.insert(END, term)

from tkinter import Tk, Frame, Menu
import sys, time, math
from tkinter import *

try:
    root = Tk()
    root.wm_title("barcode manager")
    root.geometry("250x150+300+300")
    class Example(Frame):
        def __init__(self, parent):
            Frame.__init__(self, parent)   

            self.parent = parent        
            self.initUI()

        def initUI(self):

            self.parent.title("Registered Barcodes.")

            menubar = Menu(self.parent)
            self.parent.config(menu=menubar)

            fileMenu = Menu(menubar)
            fileMenu.add_command(label="Add Barcode", command=self.Add_Barcode)
            fileMenu.add_command(label="Save", command=self.Save)
            fileMenu.add_command(label="Exit", command=self.onExit)
            menubar.add_cascade(label="File", menu=fileMenu)

            listbox = Listbox(root)
            listbox.pack(fill=BOTH, expand=1)

            def Popup_Menu():
                menu = Menu(root, tearoff=0)
                menu.add_command(label="Edit", command=lambda:print("hello"))
                menu.add_command(label="Delete", command=lambda:print(DeleteSelection(self)))

                def popup(event):
                    menu.post(event.x_root, event.y_root)

                listbox.bind("<Button-3>", popup)

            Popup_Menu()

            def get_lines():
                lines = open('lines.txt', 'r')
                for line in lines:
                    barcode, text = line.split(',')
                    text.strip('\n')
                    line = ': '.join(str(x) for x in ("GTIN #", barcode, text))
                    listbox.insert(END, line)
            get_lines()

            def DeleteSelection(self) :
                items = listbox.curselection()
                pos = 0
                for i in items :
                    idx = int(i) - pos
                    listbox.delete( idx,idx )
                    pos = pos + 1

            def Add_Barcode(self):
                import tkinter as tk
                nroot = Toplevel()
                nroot.wm_title("Add a barcode")

                textbox_lbl = Label(nroot, text="text")
                textbox_lbl.pack(side=LEFT, fill=Y)
                textbox = Entry(nroot, bd=2)
                textbox.pack(side=LEFT, fill=Y)
                textbox.pack(anchor=CENTER)

                barcode_lbl = Label(nroot, text="barcode")
                barcode_lbl.pack(side=LEFT, fill=Y)
                barcode = Entry(nroot, bd=2)
                barcode.pack(side=LEFT, fill=Y)
                barcode.pack(anchor=CENTER)

            def Add(self):
                nonlocal textbox
                nonlocal barcode
                text = textbox.get()
                barcode = barcode.get()
                nroot.destroy()
                a = 0
                for item in barcode:
                    a += 1

                if a == 7:
                    try:
                        barcode = Get_Check_Digit()
                        barcode = int(barcode)
                        print(barcode)
                        term = ': '.join(str(x) for x in ("GTIN #", barcode, text))
                        print(term)
                        listbox.insert(END, term)
                    except ():
                        error = Toplevel()
                        error.wm_title("Error")
                        error_label = Label(error, text="please enter only numbers.")    
                        error_label.pack(side=TOP, fill=X)

                else:
                    error = Toplevel()
                    error.wm_title("Error")
                    error_label = Label(error, text="Error")
                    error_label.pack(side=TOP, fill=X)
                    error_label1 = Label(error, text="please enter 7 digits")
                    error_label1.pack(side=TOP, fill=X)
                    time.sleep(5)
                    error.destroy()

            def Get_Check_Digit():
                checklist = []
                number = 1
                nonlocal barcode
                for item in barcode:
                    checkitem = int(item) * int(number)
                    checklist.append(checkitem)
                if number == 3:
                    number = 1
                elif number == 1:
                    number = 3
                checklist = sum(checklist)
                def roundup(x):
                    return int(math.ceil(x / 10.0)) * 10
                check_digit = roundup(checklist)
                check_digit -= checklist
                num = "".join(str(x) for x in (barcode, check_digit))
                return num

            btn = Button(nroot, text="Add", command=lambda:Add(self))
            btn.pack(side=BOTTOM, fill=Y)

        def Save(self):
            global listbox
            for item in listbox:
                 print(item)

        def onExit(self):
            root.destroy()
            sys.exit()
    app = Example(root)
    root.mainloop()

except ():
    pass

回答1:

If you want to use the listbox variable later in the Example class, you need to declare it with self, for example:

self.listbox = Listbox(root)

and then use it later like:

self.listbox.insert(END, term)