python - 添加父窗口 Tkinter
问题描述
我已经使用 Tkinter 开发了一个 GUI 应用程序,但现在我想升级它并添加一个登录界面。我无法做到这一点我尝试制作登录表单,然后使用 TopLevel 方法但没有运气,很多标签、按钮、条目没有显示,我将附上整个代码。这是我的课
class Student:
def __init__(self,id,first,last,major):
self.id=id
self.first=first
self.last=last
self.major=major
self.email=str(id)+'@students.liu.edu.lb'
def allinfo(self):
return 'ID={} , First_Name={} ,Last_Name={}, Major in {}, Email={}'.format(self.id,self.first,self.last,self.major,self.email)
from tkinter import *
import tkinter as tk
def log():
if(username_login_entry.get()=="admin" and password__login_entry.get()=="123"):
print("access granted")
login_screen=Tk()
login_screen.title("Login")
login_screen.geometry("300x250")
Label(login_screen, text="Please enter login details").pack()
Label(login_screen, text="").pack()
Label(login_screen, text="Username").pack()
username_login_entry = Entry(login_screen, textvariable="username")
username_login_entry.pack()
Label(login_screen, text="").pack()
Label(login_screen, text="Password").pack()
password__login_entry = Entry(login_screen, textvariable="password", show= '*')
password__login_entry.pack()
Label(login_screen, text="").pack()
Button(login_screen,command=log, text="Login", width=10, height=1).pack()
login_screen.mainloop()
我想将登录添加到这个 GUI(附上它的图像),我希望代码在成功登录后转到这个应用程序
from tkinter import *
import tkinter as tk
from student import *
from tkinter import messagebox
from tkinter import ttk
import tkinter.font as font
import pickle
import os
import cv2
num = 1
path = 'images' #Folder to store student's images
video = cv2.VideoCapture() #capture the video stream from the camera
frame = 0
tkWindow = tk.Tk() #Create a window ( UI )
tkWindow.geometry('400x180') #Window Size
tkWindow.title('Student Management System') #Window Title
with open("studentlist.dat", "rb") as fp: #Open the data file that store the student's list
SavedList = pickle.load(fp)
id = IntVar() #Var to store data
id2=IntVar() #Var to store data
fname = StringVar() #Var to store data
lname = StringVar() #Var to store data
major = StringVar() #Var to store data
idLabel = Label(tkWindow, text="Student ID : ").grid(row=0, column=0)
idEntry = Entry(tkWindow, textvariable=id).grid(row=0, column=1)
fnameLabel = Label(tkWindow, text="Student FirstName : ").grid(row=1, column=0)
lnameEntry = Entry(tkWindow, textvariable=fname).grid(row=1, column=1)
fnameLabel = Label(tkWindow, text="Student LastName : ").grid(row=3, column=0)
lnameEntry = Entry(tkWindow, textvariable=lname).grid(row=3, column=1)
majorLabel = Label(tkWindow, text="Student Major : ").grid(row=4, column=0)
majorEntry = Entry(tkWindow, textvariable=major).grid(row=4, column=1)
delLabel = Label(tkWindow, text="Delete a Student").grid(row=8, column=0)
delLabel = Label(tkWindow, text="ID of Student to Delete").grid(row=9, column=0)
delEntry = Entry(tkWindow, textvariable=id2).grid(row=9, column=1)
def RegStudent(): #Validation to Register a new student
if len( fname.get()) >0 and len(lname.get() )> 0 and len(major.get()) > 0 and id.get() > 0 :
try:
SavedList.append(Student(id.get(),fname.get(),lname.get(),major.get())) #add a student to the list
with open("studentlist.dat", "wb") as fp: #override the new list
pickle.dump(SavedList, fp)
except:
print("Error")
def takePic(): #Method to take an image and save it to Path
video = cv2.VideoCapture(0)
a = 0
while True:
a = a + 1
check, frame = video.read()
cv2.imshow("Capturing",frame)
key = cv2.waitKey(1)
if key == ord('q'):
SavePic = cv2.imwrite(os.path.join(path , fname.get()+' '+lname.get()+'.jpg'), frame)
cv2.destroyAllWindows()
break
cv2.destroyAllWindows()
video.release()
def listinfo(): # List the students along with their information
if not SavedList:
print("List is empty !")
EmptyLabel = Label(tkWindow, text="List is empty").grid(row=5, column=2)
for i in SavedList:
print(i.allinfo())
def DeleteAllStudents(): #Deletes all students
for i in SavedList:
SavedList.clear()
with open("studentlist.dat", "wb") as fp:
pickle.dump(SavedList, fp)
return
def create_window(): #creates a window onclick
window = tk.Toplevel(tkWindow)
for i in range(len(SavedList)):
Label(window, text=SavedList[i].allinfo()).grid(row=i, column=0)
def del_std(): #deletes a specific student
number=id2.get()
for i in SavedList:
if i.id==number:
SavedList.remove(i)
with open("studentlist.dat", "wb") as fp:
pickle.dump(SavedList, fp)
RegisterButton = Button(tkWindow, text="Add Student",command=RegStudent).grid(row=6, column=0)
listButton = Button(tkWindow, text="List Students",command=create_window).grid(row=6, column=1)
ClearButton = Button(tkWindow, text="Delete All Students ",command=DeleteAllStudents).grid(row=7, column=0)
TakePicButton = Button(tkWindow, text="Take picture ",command=takePic).grid(row=7, column=1)
delButton = Button(tkWindow, text="Delete ",command=del_std).grid(row=9, column=3)
tkWindow.mainloop()
解决方案
我将您的所有代码放在一个文件中,它按预期工作 - 所以我不知道问题出在哪里。
但是因为同时我对这段代码进行了一些更改——为了使它更好地组织,具有可读的名称和新的功能——所以我把它放在这里。
我希望即使没有我的描述,它也会很有用。
#from tkinter import * # PEP8: `import *` is not preferred
import os
import pickle
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import cv2
#from student import *
# --- classes ---
class Student():
def __init__(self, id_number, first_name, last_name, major):
self.id = id_number
self.first_name = first_name
self.last_name = last_name
self.major = major
def __str__(self):
return '{} | {} {} | {}'.format(self.id, self.first_name, self.last_name, self.major)
def allinfo(self):
return str(self) # `str()` will use code from `__str__`
# --- functions ---
def log(text, color='green'):
#TODO: save it in log file
# colors
# https://misc.flogisoft.com/bash/tip_colors_and_formatting
# or modules colorama, rich, etc.
if color == 'green':
print(f'\033[1;32m{text}\033[0m')
elif color == 'red':
print(f'\033[1;31m{text}\033[0m')
elif color == 'yellow':
print(f'\033[1;33m{text}\033[0m')
elif color == 'blue':
print(f'\033[1;34m{text}\033[0m')
else:
print('text')
if messages_text is not None:
messages_text.insert('end', text + "\n", color)
# ---
def login_window():
#TODO: convert it to class (and maybe put in separated file)
"""Show login window"""
def check():
username = username_login_entry.get()
password = password__login_entry.get()
if username == "admin" and password =="123":
print("access granted")
log("[INFO] access granted", 'blue')
login_screen.destroy()
login_screen = tk.Tk()
login_screen.title("Login")
tk.Label(login_screen, text="Please enter login details").pack(pady=(20,0), padx=20)
tk.Label(login_screen, text="Username").pack(pady=(20,0), padx=20)
username_login_entry = tk.Entry(login_screen, textvariable="username", bg='white')
username_login_entry.pack()
tk.Label(login_screen, text="Password").pack(pady=(20,0), padx=20)
password__login_entry = tk.Entry(login_screen, textvariable="password", show='*', bg='white')
password__login_entry.pack()
tk.Button(login_screen, text="Login", command=check, width=10).pack(pady=20, padx=20)
login_screen.mainloop()
# ----
def read_data():
log("[DEBUG] read_data(): read data from file", 'yellow')
with open("studentlist.dat", "rb") as fp:
data = pickle.load(fp)
return data
def save_data(data):
log("[DEBUG] save_data(): save data in file", 'yellow')
with open("studentlist.dat", "wb") as fp:
pickle.dump(data, fp)
def register_student():
"""Validation to Register a new student"""
first_name = first_name_var.get()
last_name = last_name_var.get()
major = major_var.get()
id_number = id1_var.get()
if first_name and last_name and major and id_number > 0:
found = False
for item in students:
if item.id == id_number:
found = True
break
if found:
log("[ERROR] register_student(): ID already exists in database", 'red')
else:
try:
item = Student(id_number, first_name, last_name, major)
students.append(item)
save_data(students)
except Exception as ex:
log("[ERROR] register_student(): " + str(ex), 'red')
else:
log("[ERROR] register_student(): wrong values", 'red')
def take_picture():
"""Take an image and save it to PATH"""
video = cv2.VideoCapture(0)
while True:
check, frame = video.read()
if check is True:
cv2.imshow("Capturing", frame)
key = cv2.waitKey(1)
if key == ord('q'):
filename = '{} {}.jpg'.format(first_name_var.get(), last_name_var.get())
fullpath = os.path.join(PATH , filename)
cv2.imwrite(fullpath, frame)
break
cv2.destroyAllWindows()
video.release()
def list_students():
"""List the students along with their information"""
if not students:
print("List is empty !")
# create label at start and here only change text
messages_text.insert('end', "List is empty\n")
for item in students:
print(item.allinfo())
def delete_all_students():
"""Deletes all students"""
students.clear()
save_data(students)
log("[INFO] delete_all_students(): Students deleted", 'blue')
def list_all_students():
"""Creates a window onclick"""
window = tk.Toplevel(tkWindow)
#for i in range(len(students)):
# tk.Label(window, text=students[i].allinfo()).grid(row=i, column=0)
if not students:
label = tk.Label(window, text="No students", bg='red')
label.grid(row=0, column=0, ipadx=50, ipady=20, sticky='news') # ipad = internal pad
log("[INFO] list_all_student(): No students", 'blue')
else:
for i, item in enumerate(students):
label = tk.Label(window, text=item.allinfo())
label.grid(row=i, column=0)
log("[INFO] list_all_student(): students " + str(len(students)), 'blue')
def delete_student():
"""Deletes a specific student"""
id_number = id2_var.get()
found = False
for item in students:
if item.id == id_number:
students.remove(item)
found = True
break
if found:
save_data(students)
log("[INFO] delete_student(): Student deleted", 'blue')
else:
log("[ERROR] delete_student(): Student not found", 'red')
# --- main ---
messages_text = None
login_window()
# - constants - (UPPER_CASE_NAMES)
PATH = 'images' # Folder to store student's images
# - variables -
#num = 1
# - rest -
try:
students = read_data()
except Exception as ex:
log("[ERROR] start: " + str(ex), 'red')
log("[DEBUG] start: create empty list of students", 'yellow')
students = []
# - window -
tkWindow = tk.Tk()
#tkWindow.geometry('400x180')
tkWindow.title('Student Management System')
# - variables which has to be created after `tk.Tk()` -
id1_var = tk.IntVar()
id2_var = tk.IntVar()
first_name_var = tk.StringVar()
last_name_var = tk.StringVar()
major_var = tk.StringVar()
# - widgets -
# - widgets - add student -
frame_add = tk.LabelFrame(tkWindow, text="Add Student")
frame_add.pack(fill="both", expand=True, padx=10, pady=10)
frame_add.columnconfigure(1, weight=1)
label = tk.Label(frame_add, text="Student ID : ", anchor="e", width=20)
label.grid(row=0, column=0, sticky='we', pady=(0,5))
entry = tk.Entry(frame_add, textvariable=id1_var, bg='white')
entry.grid(row=0, column=1, sticky='we', columnspan=2, padx=(0,5), pady=(0,5))
label = tk.Label(frame_add, text="Student First Name : ", anchor="e", width=20)
label.grid(row=1, column=0, sticky='we', pady=(0,5))
entry = tk.Entry(frame_add, textvariable=first_name_var, bg='white')
entry.grid(row=1, column=1, sticky='we', columnspan=2, padx=(0,5), pady=(0,5))
label = tk.Label(frame_add, text="Student Last Name : ", anchor="e", width=20)
label.grid(row=3, column=0, sticky='we', pady=(0,5))
entry = tk.Entry(frame_add, textvariable=last_name_var, bg='white')
entry.grid(row=3, column=1, sticky='we', columnspan=2, padx=(0,5), pady=(0,5))
label = tk.Label(frame_add, text="Student Major : ", anchor="e", width=20)
label.grid(row=4, column=0, sticky='we', pady=(0,5))
entry = tk.Entry(frame_add, textvariable=major_var, bg='white')
entry.grid(row=4, column=1, sticky='we', columnspan=2, padx=(0,5), pady=(0,5))
button = tk.Button(frame_add, text="Take picture", command=take_picture, width=12)
button.grid(row=5, column=2, sticky='we', padx=(0,5), pady=(0,5))
button = tk.Button(frame_add, text="Add Student", command=register_student, width=12)
button.grid(row=6, column=2, sticky='we', padx=(0,5), pady=(0,5))
# - widgets - delete student -
frame_delete = tk.LabelFrame(tkWindow, text="Delete Student")
frame_delete.pack(fill="both", expand=True, padx=10, pady=10)
frame_delete.columnconfigure(1, weight=1)
label = tk.Label(frame_delete, text="Student ID : ", anchor="e", width=20)
label.grid(row=0, column=0, sticky='we', pady=(0,5))
entry = tk.Entry(frame_delete, textvariable=id2_var, bg='white')
entry.grid(row=0, column=1, sticky='we', columnspan=2, padx=(0,5), pady=(0,5))
button = tk.Button(frame_delete, text="Delete ", command=delete_student, width=12)
button.grid(row=1, column=2, sticky='we', padx=(0,5), pady=(0,5))
# - widgets - other -
frame_other = tk.LabelFrame(tkWindow, text="Other Functions")
frame_other.pack(fill="both", expand=True, padx=10, pady=10)
button = tk.Button(frame_other, text="List Students", command=list_all_students)
button.grid(row=0, column=0, sticky='we', padx=(5,0), pady=(5,5))
button = tk.Button(frame_other, text="Delete All Students", command=delete_all_students)
button.grid(row=0, column=1, sticky='we', padx=(5,5), pady=(5,5))
# - widgets - messages -
frame_message = tk.LabelFrame(tkWindow, text="Messages")
frame_message.pack(fill="both", expand=True, padx=10, pady=10)
messages_text = tk.Text(frame_message, height=10, bg='black')
messages_text.pack()
for color in ['red', 'green', 'yellow', 'blue']:
messages_text.tag_config(color, foreground=color)
# - start -
tkWindow.mainloop()
Linux Mint 20 (MATE) 的屏幕截图
推荐阅读
- python - 使用 DJANGO 创建注册页面
- html - 如何查找 Google 表单 ID
- angular - Angular 8:如何将值从 *ngfor 发送到 TS 文件
- symfony - Symfony 表单 - 根据其他字段值添加必填字段以形成表单
- r - 将 SF Dataframe 写入 Microsoft SQL Server 会导致 R 崩溃并且无法写入数据
- php - API 平台 - 如何更新和嵌入关系并保留它的 id
- python - 无法从使用烧瓶的 websocket 会话中获得价值
- postgresql - Pyspark可以使用JDBC来传递Alter Table吗
- python - 一旦数据可用,如何更新 python 散景图?
- ruby-on-rails-3 - 如何仅在内存中分离与 rails-4.2 中的 has_many 关联相关的关联记录