我正在尝试使用tkinter在python中创建密码管理器。但是,当我尝试输入帐户名,用户名和密码时,它不起作用。我使用StringVar使用文本框从文本框中获取信息。我不知道该错误是在文本框中还是在写入文件中。我有以下代码:
from tkinter import *
from tkinter import messagebox
loginwin = Tk()
loginwin.wm_title("Login")
loginwin.geometry("225x75")
win = Tk()
win.wm_title("Password Manger")
win.geometry("550x215")
win.withdraw()
u = StringVar()
p = StringVar()
a = StringVar()
u1 = StringVar()
p1 = StringVar()
def login():
username1 = u.get()
password1 = p.get()
if username1 == "":
if password1 == "":
messagebox.showinfo("Login", "Login Complete")
loginwin.withdraw()
win.deiconify()
else:
messagebox.showinfo("Login", "Incorrect Password or Username")
else:
messagebox.showinfo("Login", "Incorrect Password or Username")
def add():
account1 = a.get()
username2 = u1.get()
password2 = p1.get()
account1 = str(account1)
username2 = str(username2)
password2 = str(password2)
with open("passwords.txt", "w") as file:
file.write("\n" + account1 + " " + username2 + " " + password2)
Label(loginwin, text=" Username: ").grid(row=1, column=1)
Label(loginwin, text=" Password: ").grid(row=2, column=1)
Label(loginwin, text="Hint: Nothing").grid(row=3, column=2)
Label(win, text=" Account: ").grid(row=1, column=1)
Label(win, text=" Username: ").grid(row=2, column=1)
Label(win, text=" Password: ").grid(row=3, column=1)
username = Entry(loginwin, textvariable = u)
username.grid(row=1, column=2)
password = Entry(loginwin, textvariable = p, show = "*")
password.grid(row=2, column=2)
account = Entry(win, textvariable = a)
account.grid(row=1, column=2)
username1 = Entry(win, textvariable = u1)
username1.grid(row=2, column=2)
password1 = Entry(win, textvariable = p1)
password1.grid(row=3, column=2)
login = Button(loginwin, text="Login", command=login)
login.grid(row=3, column=1)
add = Button(win, text="Add", command=add)
add.grid(row=4, column=1)
loginwin.mainloop()
win.mainloop()
答案 0 :(得分:1)
您的问题是您必须分隔Tk
根对象。
简短的版本是解决此问题的最简单(几乎可以肯定是最好)的方法是不这样做。更改此行:
win = Tk()
…对此:
win = Toplevel(loginwin)
摆脱这一行:
win.mainloop()
您可能还遇到第二个问题:通过以w
模式而不是a
模式打开文件,您正在擦除其中的任何内容,但是我怀疑那是您想要的。因此,请执行以下操作:
with open("passwords.txt", "a") as file:
如果您想了解问题所在:简短的版本是,永远不要在同一程序中拥有两个Tk
根对象,除非您真的知道自己在做什么并且有充分的理由。长版比较复杂,但是我会尝试的。
第一个问题是,每个根都有自己的单独的Tcl环境,这意味着它具有自己的单独的全局变量,这些全局变量保存着这些StringVar
的内容,依此类推。
执行此操作时:
u = StringVar()
…会在默认根目录(即您创建的第一个Py_VAR0
)中创建一个名为loginwin
的Tcl变量,并将Python变量u
附加到该Tcl变量。 / p>
执行此操作时:
account = Entry(win, textvariable = a)
…告诉条目将其文本存储在其根中名为Py_VAR0
的东西中。但其根是win
,而不是loginwin
。因此,每次文本更改时,Py_VAR0
根目录中的win
的内容都会更改,而Py_VAR0
根目录中的loginwin
的内容不会更改。
执行此操作时:
account1 = a.get()
...由于a
是Py_VAR0
的{{1}},而不是loginwin
的{{1}},因此您不会获得更改后的值, Py_VAR0
的默认值,它是一个空字符串。
其他变量也是如此。
所以,当您这样做时:
win
…您正在打开StringVar
并将其擦除(这就是 with open("passwords.txt", "w") as file:
file.write("\n" + account1 + " " + username2 + " " + password2)
模式的意思),然后编写:
passwords.txt
…实际上并不是什么,但是在您的文本编辑器中可能看起来像什么都没有,因为它只是一个2行文件,第一行没有任何内容,第二行有两个空格。
您可以通过像其他任何Tkinter对象一样,显式地为每个w
赋予正确的根作为父级来解决此问题:
"\n" + "" + " " + "" + " " + ""
第二个问题是每个根都需要自己的StringVar
。
一个接一个运行就意味着第二个直到第一个退出后才开始运行。这意味着在u = StringVar(win)
退出之前,附加到mainloop
上任何窗口小部件的任何代码都不会运行。
这意味着您的win
未处于活动状态并正在接收事件,因此甚至不会设置错误字符串变量;只是根本不会做任何事情。
解决此问题的唯一方法是手动将两个回路交织在一起-一个驱动器另一个驱动器。 那并不难,但也不是那么简单。
但是要解决这两个问题,更简单的方法是没有两个根源。
如果由于某种原因确实确实需要两个单独的根,则必须正确管理它们的变量和主循环。
但是,如果要这样做是因为您想要另一个顶层窗口,请使用loginwin
。
如果您由于其他原因而这样做……好吧,这取决于您为什么这样做,但是拥有两个根源可能不是正确的答案。
答案 1 :(得分:0)
您的代码有几个问题。
您正在使用<var>.get()
来获取条目中的文本,但如果尝试打印其输出,则将获得条目名称,而不是文本。使用<entry>.get()
获取文本。
您正在使用open("<file>","w")
,而模式w
用于重写文件。我建议您使用模式a
,该模式会自动在文件末尾附加数据。
写入数据后,您没有关闭文件。
add
是函数的名称,但是您正在命名add
的按钮。与login
类似。给这些按钮起一个不同的名字。
您更新的代码是:
from tkinter import *
from tkinter import messagebox
loginwin = Tk()
loginwin.wm_title("Login")
loginwin.geometry("225x75")
win = Tk()
win.wm_title("Password Manger")
win.geometry("550x215")
win.withdraw()
u = StringVar()
p = StringVar()
a = StringVar()
u1 = StringVar()
p1 = StringVar()
def login():
username1 = u.get()
password1 = p.get()
print(username1,password1)
if username1 == "":
if password1 == "":
messagebox.showinfo("Login", "Login Complete")
loginwin.withdraw()
win.deiconify()
else:
messagebox.showinfo("Login", "Incorrect Password or Username")
else:
messagebox.showinfo("Login", "Incorrect Password or Username")
def add():
account11 = str(account.get())
username22 = str(username1.get())
password22 = str(password1.get())
file = open("passwords.txt", "a")
file.write("\n" + account11 + " " + username22 + " " + password22)
file.close()
Label(loginwin, text=" Username: ").grid(row=1, column=1)
Label(loginwin, text=" Password: ").grid(row=2, column=1)
Label(loginwin, text="Hint: Nothing").grid(row=3, column=2)
Label(win, text=" Account: ").grid(row=1, column=1)
Label(win, text=" Username: ").grid(row=2, column=1)
Label(win, text=" Password: ").grid(row=3, column=1)
username = Entry(loginwin, textvariable = u)
username.grid(row=1, column=2)
password = Entry(loginwin, textvariable = p, show = "*")
password.grid(row=2, column=2)
account = Entry(win, textvariable = a)
account.grid(row=1, column=2)
username1 = Entry(win, textvariable = u1)
username1.grid(row=2, column=2)
password1 = Entry(win, textvariable = p1)
password1.grid(row=3, column=2)
button_login = Button(loginwin, text="Login", command=login)
button_login.grid(row=3, column=1)
button_add = Button(win, text="Add", command=add)
button_add.grid(row=4, column=1)
loginwin.mainloop()
win.mainloop()