简体   繁体   中英

Python: Search function in GUI with regex requires global variables, but UnboundLocal Error

This is my first project I am a complete beginner, so my apologies.

I am attempting to create a inventory system with a GUI. Where I ran into issues was handling all the data, I thought before learning SQLite I should attempt my own crappy data organizing that way I have a deeper understanding of the necessity of that library. Currently I have been stuck on the search function for weeks. My data is "organized" in a text file, it is comprised of a class with 6 variables. The variables are stored to the text file as follows; x1, x2, x3, x4, x5, x6.

Currently I am attempting to create a search function using regex that can find the entire class (x1-x6) by searching either x1, x2, or x3.

The problem I am having is that my search values (x_search_nick(x1), x_search_name(x2), or x_search_part(x3)) are all defined by entries in a search window within the GUI. When I hit the search button I would like it to display in a separate window the entire classes attributes of that search value. In order for it to be a separate window it needs to be a separate function, but at that point the search variables need to be defined globally. When making all search variables global I get "UnboundLocalError: unbound local error python local variable referenced before assignment", I believe because if searching using x1, x2, or x3 two of the variables will be empty? Either way I've tried setting it up in many different ways and can't seem to find the right way.

I also am very bad at phrasing this entire question so I will just throw my code out there and hopefully with this info and the code the problem will be easier to see. Along with the code I have a text file Reagent_To_List.txt. Again this is my first project, organization and such are a wreck.

Thank you.

from tkinter import *
import tkinter.messagebox
import re
#Tkinter Basics______________________________________________
root = Tk()
#Files to open_______________________________________________
Reagent_To_List_file = open("Reagent_To_List.txt","w")

topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)

#Class_____________________________________

class Reagent:
    def __init__(self, Nickname, Name, Part_Num, Lot_Num, Expiration,         
Manufacteur, ):
    self.Nickname = Nickname
    self.Name = Name
    self.Part_Num = Part_Num
    self.Lot_Num = Lot_Num
    self.Expiration = Expiration
    self.Manufacteur = Manufacteur

#Functions_________________________________

class New_Reagent_Button_1:

    def __init__(self, master):
        frame = Frame(master)
        frame.pack()

        self.New_Reagent_button =Button(topFrame, text="New Reagent",fg="Black", width=75, height=3, relief=RAISED, bd=18,command = self.new_Reg)
    self.New_Reagent_button.grid(row=0, column=0)



def new_Reg(self):
    newwin = Toplevel(root)
    newwin.geometry("450x500")

    Enter_Nick = Label(newwin, text = "Enter Nickname: ", bd = 25)
    Enter_Nick.grid(row=0, column=0)
    x = Entry(newwin, bd = 5, width=30)
    x.grid(row=0, column=1)

    Enter_Chem_Name = Label(newwin, text="Chemical Name: ", bd = 25)
    Enter_Chem_Name.grid(row=1, column=0)
    x_1 = Entry(newwin, bd=5, width=30)
    x_1.grid(row=1, column=1)

    Enter_Part = Label(newwin, text="Part Number: ", bd=25)
    Enter_Part.grid(row=2, column=0)
    x_2 = Entry(newwin, bd=5, width=30)
    x_2.grid(row=2, column=1)

    Enter_Lot = Label(newwin, text = "Lot Number: ", bd= 25)
    Enter_Lot.grid(row=3, column=0)
    x_3 = Entry(newwin, bd=5, width=30)
    x_3.grid(row=3, column=1)

    Enter_Exp = Label(newwin, text = "Expiration Date: ", bd= 25)
    Enter_Exp.grid(row=4, column=0)
    x_4 = Entry(newwin, bd=5, width=30)
    x_4.grid(row=4, column=1)

    Enter_Manu = Label(newwin, text = "Manufacteur: ", bd= 25)
    Enter_Manu.grid(row=5, column=0)
    x_5 = Entry(newwin, bd=5, width=30)
    x_5.grid(row=5, column=1)


    def Done_Save(x):
        input = x.get()
        input_1 = x_1.get()
        input_2 = x_2.get()
        input_3 = x_3.get()
        input_4 = x_4.get()
        input_5 = x_5.get()

        Reagent_To_List = (Reagent(x,x_1, x_2, x_3, x_4, x_5))
        Reagent_To_List_file.write(str(input + ", "))
        Reagent_To_List_file.write(str(input_1 + ", "))
        Reagent_To_List_file.write(str(input_2 + ", "))
        Reagent_To_List_file.write(str(input_3 + ", "))
        Reagent_To_List_file.write(str(input_4 + ", "))
        Reagent_To_List_file.write(str(input_5))
        Reagent_To_List_file.write("\n")
        Reagent_To_List_file.flush()

    Save_New_Reg = Button(newwin, text="Done/Save", bd=5, height=2, width= 8, command= lambda: Done_Save(x))
    Save_New_Reg.grid(row=6, column=0)

    Done_New_Reg = Button(newwin, text ="Exit", bd = 5, height = 2, width = 8, command = newwin.destroy)
    Done_New_Reg.grid(row = 6, column = 2)

    newwin.mainloop()


class Search_Button:

def __init__(self, master):
    frame = Frame(master)
    frame.pack()

    self.Search_button =Button(topFrame, text="Search For Reagent", fg="Black", width=75, height=3, relief=RAISED, bd=18, command = self.Search)
    self.Search_button.grid(row=1, column=0)

def Search(self):

    newwin = Toplevel(root)
    newwin.geometry("610x400")

    Enter_Search = Label(newwin, text="Enter\n Nickname: ", bd=25)
    Enter_Search.grid(row=0, column=0)
    global x_search_nick
    x_search_nick = Entry(newwin, bd=5, width=50)
    x_search_nick.grid(row=0, column=1)

    Enter_Search = Label(newwin, text="Enter\n Chemical Name: ", bd=25)
    Enter_Search.grid(row=3, column=0)
    global x_search_name
    x_search_name = Entry(newwin, bd=5, width=50)
    x_search_name.grid(row=3, column=1)

    Enter_Search = Label(newwin, text="Enter\n Part #: ", bd=25)
    Enter_Search.grid(row=6, column=0)
    global  x_search_part
    x_search_part = Entry(newwin, bd=5, width=50)
    x_search_part.grid(row=6, column=1)

    Done_New_Search = Button(newwin, text = "Exit", bd = 5, height = 2, width = 8, command = newwin.destroy)
    Done_New_Search.grid(row = 9, column = 2)

    B_Search = Button(newwin, text="Search", bd=5, height=2, width=8, command= self.Search_Function)
    B_Search.grid(row=9, column=0)






def Search_Function(self):

    newwin = Toplevel(root)
    newwin.geometry("550x700")

    Results_Header = Label(newwin, text="Search Results", font=("Times New Roman", 16), height=5, width=10)
    Results_Header.grid(row=0, column=1)
    Search_Results_List = Listbox(newwin, bd=3, height=20, width=50)
    Search_Results_List.grid(row=10, column=4)

        regex_nick = (x_search_nick.get()) + r"([a-zA-z0-9\-\/]+),\s([a-zA-z0-9\-\/]+),\s([a-zA-z0-9\-\/]+),\s([a-zA-z0-9\-\/]+),\s([a-zA-z0-9\-\/]+)"
    pattern_nick = re.compile(regex_nick)

    with open("Reagent_To_List.txt", "r") as f:
        contents = f.read()
        matches_nick = pattern_nick.finditer(contents)

        for match_nick in matches_nick:
            print(match_nick)
            return (match_nick)

            if match_nick.group(1) == x_search_nick.get():
                Search_Results_List.insert(1, x_search_nick.get() + ", " + match_nick.group(2) + ", " + match_nick.group(3) + ", " + match_nick.group(4) + ", " + match_nick.group(5) + ", " + match_nick.group(6))

    regex_name = (r"([a-zA-z0-9\-\/]+),\s" + x_search_name.get() + ",\s([a-zA-z0-9\-\/]+),\s([a-zA-z0-9\-\/]+),\s([a-zA-z0-9\-\/]+),\s([a-zA-z0-9\-\/]+)")
    pattern_name = re.compile(regex_name)

    with open("Reagent_To_List.txt", "r") as f:
        contents = f.read()
        matches_name = pattern_name.finditer(contents)

        for match_name in matches_name:
            print(match_name)
            return (match_name)

            if match_name.group(2) == x_search_name:
                Search_Results_List.insert(1, match_name.group(1) + ", " + x_search_name.get() + ", " + match_name.group(3) + ", " + match_name.group(4) + ", " + match_name.group(5) + ", " + match_name.group(6))

    regex_part = (r"([a-zA-z0-9\-\/]+),\s([a-zA-z0-9\-\/]+),\s" + (x_search_part.get()) + ",\s([a-zA-z0-9\-\/]+),\s([a-zA-z0-9\-\/]+),\s([a-zA-z0-9\-\/]+),\s([a-zA-z0-9\-\/]+)")
    pattern_part = re.compile(regex_part)

    with open("Reagent_To_List.txt", "r") as f:
        contents = f.read()
        matches_part = pattern_part.finditer(contents)

        for match_part in matches_part:
            print(match_part)
            return (match_part)

            if match_part.group(3) == x_search_part:
                Search_Results_List.insert(1, match_part.group(1) + ", " + match_part.group(2) + ", " + x_search_part.get() + ", " + match_part.group(4) + ", " + match_part.group(5) + ", " + match_part.group(6))

    scrollbar = Scrollbar(newwin, orient="vertical")
    scrollbar.config(command=Search_Results_List.yview)
    scrollbar.grid(row=10, column=5, sticky="ns")

    #except:
       # Error_Header = Label(newwin, text="Search Yielded No Results",  width = 30, height = 20, font= ("Times New Roman",20) )
        #Error_Header.grid(row=5, column=4)
        #print(error)


#Buttons____________________________________

New_b = New_Reagent_Button_1(root)
Search_b = Search_Button(root)

button_Edit_Reagent = Button(topFrame, text="Edit Reagent", fg="Black", width = 75, height = 3, relief = RAISED,bd= 18)
button_Delete_Reagent = Button(topFrame, text="Delete Reagent", fg="Red", width = 75, height = 3, relief = RAISED,bd= 18)
button_See_Reagent_List = Button(topFrame, text="See Reagent List", fg="Black", width = 75, height = 3, relief = RAISED,bd= 18)
button_Check_Expired = Button(topFrame, text="Check Expired", fg="Red", width = 75, height = 3, relief = RAISED,bd= 18)
button_Done = Button(topFrame, text="Done", fg="Red", width = 75, height = 3, relief = RAISED,bd= 18,command = root.destroy)


button_Edit_Reagent.grid(row=6, column=0)
button_Delete_Reagent.grid(row=7, column=0)
button_See_Reagent_List.grid(row=9, column=0)
button_Check_Expired.grid(row=11, column=0)
button_Done.grid(row=12, column=0)


root.mainloop()

It seems to me the Reagent_To_List.txt file, which is created outside of the scope of the Search_Function , is causing your issue.

If you add a txt_file argument in the Search_Function(self, txt_file) and replace all the Reagent_To_List.txt, within the function, with txt_file , then call the function Search_Function(root, "Reagent_To_List.txt") it should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM