单击按钮时出错:NameError: name is not defined

Posted

技术标签:

【中文标题】单击按钮时出错:NameError: name is not defined【英文标题】:Error when clicking on button: NameError: name is not defined 【发布时间】:2021-10-26 02:47:40 【问题描述】:

我有一个带有 Tkinter 的小窗口,用于在数据库中插入、更新和删除字段。该窗口由 Treeview 排名、插入文本的文本框和按钮组成:插入、更新、删除。

问题:当我单击“更新”或“删除”按钮时,出现以下错误(错误与两者相同,即 selected_item 更新,selected_item 删除)

NameError: name 'selected_item' is not defined

这是我使用的代码。有点长,但是还是挺简单直观的(我去掉了一些对操作有用的部分,为了加长代码,提高可读性):

# GUI
frame_search = Frame(app)
frame_search.grid(row=0, column=0)
barrasopra=Frame(app, width=2200, height=47, background="#d9d9d9")
barrasopra.place(x=1, y=1)
barradue=Frame(app, width=2200, height=47, background="#78c030")
barradue.place(x=1, y=47)


#CLASS DATABASE

class Database:
    def __init__(self, db):
        self.conn = sqlite3.connect(db)
        self.cur = self.conn.cursor()
        self.cur.execute(
            "CREATE TABLE IF NOT EXISTS routers (id INTEGER PRIMARY KEY, Relaz_Campionato integer, Relaz_Giornata integer, Data numeric, Ora numeric, Relaz_Sq1 integer, Relaz_Sq2 integer, Risultato_Sq1 integer, Risultato_Sq2 integer)")
        self.conn.commit()

    def fetch(self, hostname=''):
        self.cur.execute(
            "SELECT * FROM routers WHERE hostname LIKE ?", ('%'+hostname+'%',))
        rows = self.cur.fetchall()
        return rows

    def fetch2(self, query):
        self.cur.execute(query)
        rows = self.cur.fetchall()
        return rows

    def insert(self, Relaz_Campionato, Relaz_Giornata, Data, Ora, Relaz_Sq1, Relaz_Sq2, Risultato_Sq1, Risultato_Sq2):
        self.cur.execute("INSERT INTO ARCHIVIO_Risultati VALUES (NULL, ?, ?, ?, ?, ?, ?, ?, ?)",
                         (Relaz_Campionato, Relaz_Giornata, Data, Ora, Relaz_Sq1, Relaz_Sq2, Risultato_Sq1, Risultato_Sq2))
        self.conn.commit()

    def remove(self, id):
        self.cur.execute("DELETE FROM routers WHERE id=?", (id,))
        self.conn.commit()

    def update(self, id, Relaz_Campionato, Relaz_Giornata, Data, Ora, Relaz_Sq1, Relaz_Sq2, Risultato_Sq1, Risultato_Sq2):
        self.cur.execute("UPDATE ARCHIVIO_Risultati SET Relaz_Campionato = ?, Relaz_Giornata = ?, Data = ?, Ora = ?, Relaz_Sq1 = ?, Relaz_Sq2 = ?, Risultato_Sq1 = ?, Risultato_Sq2 = ? WHERE id = ?",
                         (Relaz_Campionato, Relaz_Giornata, Data, Ora, Relaz_Sq1, Relaz_Sq2, Risultato_Sq1, Risultato_Sq2, id))
        self.conn.commit()

    def __del__(self):
        self.conn.close()


conn= sqlite3.connect('/home/db.db')
cur= conn.cursor()
db= Database('/home/db.db')


def select_router(event):
    try:
        global selected_item
        index = router_tree_view.selection()[0]
        selected_item = router_tree_view.item(index)['values']


        Relaz_Campionato_entry.delete(0, END)
        Relaz_Campionato_entry.insert(END, selected_item[1])

        Relaz_Giornata_entry.delete(0, END)
        Relaz_Giornata_entry.insert(END, selected_item[2])
        #######################################################
        Data_entry.delete(0, END)
        Data_entry.insert(END, selected_item[3])
        
        Ora_entry.delete(0, END)
        Ora_entry.insert(END, selected_item[4])
        
        Relaz_Sq1_entry.delete(0, END)
        Relaz_Sq1_entry.insert(END, selected_item[5])
        
        Relaz_Sq2_entry.delete(0, END)
        Relaz_Sq2_entry.insert(END, selected_item[6])

        Risultato_Sq1_entry.delete(0, END)
        Risultato_Sq1_entry.insert(END, selected_item[7])

        Risultato_Sq2_entry.delete(0, END)
        Risultato_Sq2_entry.insert(END, selected_item[8])

       
    except IndexError:
        pass

def remove_router():
    db.remove(selected_item[0])
    clear_text()
    populate_list()

def update_router():
    db.update(selected_item[0], Relaz_Campionato_text.get(), Relaz_Giornata_text.get(), Data_text.get(), Ora_text.get(), Relaz_Sq1_text.get(),
                Relaz_Sq2_text.get(), Risultato_Sq1_text.get(), Risultato_Sq2_text.get())  
    populate_list()

def clear_text():
    Data_entry.delete(0, END)
    Ora_entry.delete(0, END)
    Relaz_Sq1_entry.delete(0, END)
    Relaz_Sq2_entry.delete(0, END)
    Risultato_Sq1_entry.delete(0, END)    
    Risultato_Sq2_entry.delete(0, END)                           

def execute_query():
    query = query_search.get()
    populate_list2(query)


# FIELDS DATABASE
# Data
Data_text = StringVar()
Data_label = Label(app, text='Data', font=('bold', 11), bg='#f0f0f0', foreground='black')
Data_label.place(x=6, y=380)

Data_entry = Entry(app, textvariable=Data_text)
Data_entry.place(x=180, y=380)

# Ora
Ora_text = StringVar()
Ora_label = Label(app, text='Ora', font=('bold', 11), bg='#f0f0f0', foreground='black')
Ora_label.place(x=6, y=420)
Ora_entry = Entry(app, textvariable=Ora_text)
Ora_entry.place(x=180, y=418)

and others that I don't write 



#FRAME RISULTATI, CON VISUALIZZAZIONE AD ALBERO

frame_router = Frame(app, bg='#d9d9d9')
frame_router.place(x=6, y=105)

columns = ['id', 'Data', 'Ora', 'Sq1', 'Sq2', 'Risultat1', 'Risultato2']
router_tree_view = Treeview(frame_router, columns=columns, show="headings")
router_tree_view.column("id", width=30)
for col in columns[1:]:
    
    router_tree_view.column(col, width=170)
    router_tree_view.heading(col, text=col)
    
router_tree_view.bind('<<TreeviewSelect>>', select_router)
router_tree_view.pack(side="left", fill="y")
scrollbar = Scrollbar(frame_router, orient='vertical')
scrollbar.configure(command=router_tree_view.yview)
scrollbar.pack(side="right", fill="y")
router_tree_view.config(yscrollcommand=scrollbar.set)

#COLORE TABELLA
style = ttk.Style(app)
style.configure("Treeview",
                background="white",
                foreground="#000000",
                rowheight=25,
                fieldbackground="white")
style.map('Treeview', background=[('selected', '#99d260')])


#RECALL BUTTONS 
def populate_list(hostname=''):
    for i in router_tree_view.get_children():
        router_tree_view.delete(i)
    for row in db.fetch(hostname):
        router_tree_view.insert('', 'end', values=row)

def populate_list2(query='select * from routers'):
    for i in router_tree_view.get_children():
        router_tree_view.delete(i)
    for row in db.fetch2(query):
        router_tree_view.insert('', 'end', values=row)

def add_router():
 if Relaz_Campionato_text.get() == '' or Relaz_Giornata_text.get() == '' or Data_text.get() == '' or Ora_text.get() == '' or Relaz_Sq1_text.get() == '' or Relaz_Sq2_text.get() == '' or Risultato_Sq1_text.get() =='' or Risultato_Sq2_text.get()=='':
     messagebox.showerror('Required Fields', 'Please include all fields')
     return
 db.insert(Relaz_Campionato_text.get(), Relaz_Giornata_text.get(), Data_text.get(), Ora_text.get(), Relaz_Sq1_text.get(), Relaz_Sq2_text.get(), Risultato_Sq1_text.get(), Risultato_Sq2_text.get())
 clear_text()
 populate_list()


#Populate data
populate_list()



#BUTTON
frame_btns = Frame(app, bg='#d9d9d9')
frame_btns.place(y=2)

add_btn = Button(frame_btns, text='Aggiungi nuovo', width=12, bg='#78c030', command=add_router)
add_btn.grid(row=0, column=0, pady=7, padx=7)

remove_btn = Button(frame_btns, text='Rimuovi',
                    width=12, bg='#78c030', command=remove_router)
remove_btn.grid(row=0, column=1, padx=7)

update_btn = Button(frame_btns, text='Aggiorna',
                    width=12, bg='#78c030', command=update_router)
update_btn.grid(row=0, column=2, padx=7)

clear_btn = Button(frame_btns, text='Pulisci',
                   width=12, bg='#78c030', command=clear_text)
clear_btn.grid(row=0, column=3, padx=7)

【问题讨论】:

这个错误的意思正是它所说的。通常,这意味着代码的执行顺序是定义它的代码在使用它的代码之后才会运行。几个print 声明应该能够证明这一点。设置时调用print,使用时再调用一次,看看打印语句在控制台中出现的顺序。 @BryanOakley 我想我明白了,但也许不是。我是 Python 新手。你能告诉我如何取悦我吗?我很抱歉给您带来麻烦。谢谢 您需要确保在按下更新或删除按钮之前调用 select_router。否则它不会被定义导致错误。另一种解决方案是在开头说:selected_item = "" 并签入删除或更新路由器功能if selected_item == ""。如果是这种情况,那么只需停止执行函数(使用return)或要求用户选择一个路由器,以便 selected_item 的值不同于“”。 @sputnick567 我试图在点击按钮之前调用 select_router,但这给了我其他问题(我从网上复制了代码,代码已经有点缺陷)。我可以在答案中说明您正在谈论的解决方案吗?我如何使用 if selected_item = "" 编写代码并返回?谢谢(抱歉,我是 Python 新手) @BryanOakley 我从网上得到了这段代码。它有点缺陷,给了我其他错误。我试图修复它,至少现在窗口启动了。除了我上面提到的错误出现在我身上。我知道这是一个订单问题,我试图修复它,但我不能。我能帮帮我吗?我不能。谢谢 【参考方案1】:

这通常是因为区分大小写、拼写错误或一开始就忘记定义它。如果不是以上问题,使用前需要检查是否定义了 selected_item。如果是在调用之前定义的,那么检查是否有删除它的东西,比如del selected_item,可以随时打印出变量看看是什么。

【讨论】:

以上是关于单击按钮时出错:NameError: name is not defined的主要内容,如果未能解决你的问题,请参考以下文章

单击按钮时将按钮的图像从图像更改为另一个时出错

单击播放按钮时,AVAudioPlayer 的问题会出错

如何在按钮单击时更新datagridview中的记录?

单击第二个活动上的按钮在视图上执行“单击”或“滚动到”时出错

单击按钮以转到从 Spinner 选择的下一个活动时出错

尝试单击隐藏然后再次可见的元素时出错