如何在 tkinter 中覆盖文本文件中的数据
How to overwrite data in text file in tkinter
我正在使用 tkinter 创建一个程序,它带有存储在文本文件中的默认名称和密码。登录后,您需要打开 Toplevel
window 并输入您希望在后续登录中使用的名称和密码。我已经定义了我的变量,但如果我想覆盖文本文件,我会收到以下内容:
Error "NameError: name 'e1' is not defined"
我知道我已经定义了。
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20).pack()
e2 = Entry(ch, width=20).pack()
sb = Button(ch, text="save", command=save_changes).pack()
def save_changes(): # function to change data in the txt file
data = e1.get() + "\n " + e2.get()
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
所以你在这里有几个选择,但一般来说你有 2 个主要问题。
第一个问题是在创建 e1
和 e2
输入字段后使用 .pack()
。这是 get()
方法的问题,因为如果您以这种方式打包,几何管理器将 return None
。正确的方法是先用 e1 = Entry(ch, width=20)
创建小部件,然后在下一行用 e1.pack()
打包它,这将允许 get()
在 e1
.[=42= 上工作]
第二个问题是局部变量和全局变量的问题。您在函数 change_login()
中创建了 e1
和 e2
,并且没有告诉 python e1
和 e2
是全局变量,它将自动假定您希望它们作为局部变量。这意味着变量只能从创建它们的函数中访问。
你有几个选项,我会为你分解。
1) 快速而肮脏的选择是将 e1
和 e2
分配为全局变量。这可以通过使用 global var_name, var2_name, and_so_on
来完成,因此在这种情况下,将此行添加到 change_login():
和 save_changes()
函数的顶部:
global e1, e2
这很好地告诉 python 添加 e1
和 e2
到全局名称 space 并且它将允许 save_changes()
使用变量全局名称 space.
2) 另一种方法是使用按钮命令将 2 个变量传递给 save_changes()
。为此,我们需要使用 lambda
,我们可以通过添加:
来完成此操作
command = lambda e1=e1, e2=e2: save_changes(e1, e2)
添加到 change_login()
中创建的按钮,并将 2 个参数添加到 save_changes()
,如下所示:
save_changes(e1, e2)
这与第一个选项一样有效,而且还避免了使用全局变量。
3) 第三种选择是将整个程序创建为 class 并使用 class 属性以允许变量与 class 中的所有方法一起使用。
下面是您使用第一个选项的代码示例:
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
global e1, e2
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20)
e1.pack()
e2 = Entry(ch, width=20)
e2.pack()
sb = Button(ch, text="save", command=save_changes).pack()
def save_changes(): # function to change data in the txt file
global e1, e2
data = e1.get() + "\n" + e2.get() # removed space after \n
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
下面是您使用第二个选项的代码示例:
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20)
e1.pack()
e2 = Entry(ch, width=20)
e2.pack()
Button(ch, text="save", command=lambda e1=e1, e2=e2: save_changes(e1, e2)).pack()
def save_changes(e1, e2): # function to change data in the txt file
data = e1.get() + "\n" + e2.get() # removed space after \n
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
下面是您的代码转换为 class 并使用 class 属性以避免使用全局变量的示例。
import sys
from tkinter import messagebox
from tkinter import *
class MyApp(Frame):
def __init__(self, master, *args, **kwargs):
Frame.__init__(self, master, *args, **kwargs)
self.master = master
self.master.withdraw()
self.log = Toplevel()
self.master.geometry("350x350")
self.log.geometry("200x200")
self.entry1 = Entry(self.log)
self.entry2 = Entry(self.log)
self.button1 = Button(self.log, text="Login", command=self.login_in)
self.entry1.pack()
self.entry2.pack()
self.button1.pack()
Label(root, text="welcome").pack()
Button(root, text="change data in file", command=self.change_login).pack()
def login_in(self):
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if self.entry1.get() == name and self.entry2.get() == password:
self.master.deiconify()
self.log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login(self):
ch = Toplevel(self.master)
ch.geometry('300x300')
self.e1 = Entry(ch, width=20)
self.e1.pack()
self.e2 = Entry(ch, width=20)
self.e2.pack()
Button(ch, text="save", command=self.save_changes).pack()
def save_changes(self):
data = "{}\n{}".format(self.e1.get(), self.e2.get())
with open("pass.txt", "w") as f:
f.writelines(data)
if __name__ == "__main__":
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
root = Tk()
app = MyApp(root)
root.mainloop()
我正在使用 tkinter 创建一个程序,它带有存储在文本文件中的默认名称和密码。登录后,您需要打开 Toplevel
window 并输入您希望在后续登录中使用的名称和密码。我已经定义了我的变量,但如果我想覆盖文本文件,我会收到以下内容:
Error "NameError: name 'e1' is not defined"
我知道我已经定义了。
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20).pack()
e2 = Entry(ch, width=20).pack()
sb = Button(ch, text="save", command=save_changes).pack()
def save_changes(): # function to change data in the txt file
data = e1.get() + "\n " + e2.get()
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
所以你在这里有几个选择,但一般来说你有 2 个主要问题。
第一个问题是在创建 e1
和 e2
输入字段后使用 .pack()
。这是 get()
方法的问题,因为如果您以这种方式打包,几何管理器将 return None
。正确的方法是先用 e1 = Entry(ch, width=20)
创建小部件,然后在下一行用 e1.pack()
打包它,这将允许 get()
在 e1
.[=42= 上工作]
第二个问题是局部变量和全局变量的问题。您在函数 change_login()
中创建了 e1
和 e2
,并且没有告诉 python e1
和 e2
是全局变量,它将自动假定您希望它们作为局部变量。这意味着变量只能从创建它们的函数中访问。
你有几个选项,我会为你分解。
1) 快速而肮脏的选择是将 e1
和 e2
分配为全局变量。这可以通过使用 global var_name, var2_name, and_so_on
来完成,因此在这种情况下,将此行添加到 change_login():
和 save_changes()
函数的顶部:
global e1, e2
这很好地告诉 python 添加 e1
和 e2
到全局名称 space 并且它将允许 save_changes()
使用变量全局名称 space.
2) 另一种方法是使用按钮命令将 2 个变量传递给 save_changes()
。为此,我们需要使用 lambda
,我们可以通过添加:
command = lambda e1=e1, e2=e2: save_changes(e1, e2)
添加到 change_login()
中创建的按钮,并将 2 个参数添加到 save_changes()
,如下所示:
save_changes(e1, e2)
这与第一个选项一样有效,而且还避免了使用全局变量。
3) 第三种选择是将整个程序创建为 class 并使用 class 属性以允许变量与 class 中的所有方法一起使用。
下面是您使用第一个选项的代码示例:
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
global e1, e2
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20)
e1.pack()
e2 = Entry(ch, width=20)
e2.pack()
sb = Button(ch, text="save", command=save_changes).pack()
def save_changes(): # function to change data in the txt file
global e1, e2
data = e1.get() + "\n" + e2.get() # removed space after \n
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
下面是您使用第二个选项的代码示例:
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20)
e1.pack()
e2 = Entry(ch, width=20)
e2.pack()
Button(ch, text="save", command=lambda e1=e1, e2=e2: save_changes(e1, e2)).pack()
def save_changes(e1, e2): # function to change data in the txt file
data = e1.get() + "\n" + e2.get() # removed space after \n
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
下面是您的代码转换为 class 并使用 class 属性以避免使用全局变量的示例。
import sys
from tkinter import messagebox
from tkinter import *
class MyApp(Frame):
def __init__(self, master, *args, **kwargs):
Frame.__init__(self, master, *args, **kwargs)
self.master = master
self.master.withdraw()
self.log = Toplevel()
self.master.geometry("350x350")
self.log.geometry("200x200")
self.entry1 = Entry(self.log)
self.entry2 = Entry(self.log)
self.button1 = Button(self.log, text="Login", command=self.login_in)
self.entry1.pack()
self.entry2.pack()
self.button1.pack()
Label(root, text="welcome").pack()
Button(root, text="change data in file", command=self.change_login).pack()
def login_in(self):
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if self.entry1.get() == name and self.entry2.get() == password:
self.master.deiconify()
self.log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login(self):
ch = Toplevel(self.master)
ch.geometry('300x300')
self.e1 = Entry(ch, width=20)
self.e1.pack()
self.e2 = Entry(ch, width=20)
self.e2.pack()
Button(ch, text="save", command=self.save_changes).pack()
def save_changes(self):
data = "{}\n{}".format(self.e1.get(), self.e2.get())
with open("pass.txt", "w") as f:
f.writelines(data)
if __name__ == "__main__":
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
root = Tk()
app = MyApp(root)
root.mainloop()