I am working an a tool where-in I am getting the initial user credentials and an unique identifier via Tkinter GUI interface. Post that after a lot of data fetching and processing I would get a report into an excel sheet using xlsxwriter package.
I generally exit/close the tkinter window using destroy() method on click of a button. Here, I want to show the user the status of the report creation in a Tkinter messagebox and then close the main window.
Note: I am using .pyw extension, so that the end user who is using the tool shouldn't see the console. So once the user hits the submit button, I will show a label at the footer of the window saying "Processing ..."
Sample code:
from tkinter import *
#Some other libraries are imported
mScrn = Tk()
mScrn.title("Report Generation Tool v1.0")
mScrn.geometry("200x180")
mScrn.resizable(False, False)
tk_uid_lbl = Label(mScrn, text="MVS1 Username")
tk_uid_lbl.pack()
tk_uid_lbl.place(x=20,y=20)
uid = StringVar()
tk_uid = Entry(mScrn, bd=3, textvariable=uid)
tk_uid.pack()
tk_uid.place(x=150, y=20)
tk_pwd_lbl = Label(mScrn, text="MVS1 Password")
tk_pwd_lbl.pack()
tk_pwd_lbl.place(x=20,y=60)
pwd = StringVar()
tk_pwd = Entry(mScrn, bd=3, show='*', textvariable=pwd)
tk_pwd.pack()
tk_pwd.place(x=150, y=60)
tk_ver_lbl = Label(mScrn, text="Version #")
tk_ver_lbl.pack()
tk_ver_lbl.place(x=20,y=100)
ver = StringVar()
tk_ver=Entry(mScrn, bd=3, textvariable=ver)
tk_ver.pack()
tk_ver.place(x=150, y=100)
tk_sub_button = Button(text='Submit', command = show_footer)
tk_sub_button.pack()
tk_sub_button.place(x=150, y=150)
mScrn.mainloop()
#The data provided in the GUI is used for access and a lot of process goes on
#Close the Tkinter window post the process is done
Thanks in Advance. I am using Python3
I am having a hard time understanding your question. My understanding is that using destroy() is exactly what you are looking for. Use destroy() when you are finished. You basically already answered your own question. I would find it helpful if you could explain your question more thoroughly. I agree with Goyo but I cannot comment.
I don't know how to get the data before closing the mainloop(). In
that aspect once that is closed I cannot show the label on the GUI and
then close with user consent (i.e. after clicking 'ok' in message box)
I don't undestand where is your problem, you can save your data with a lot ways, list, module, object, file, etc.
import tkinter as tk
import random
import threading
import time
# Simulate a process
def get_data(callback):
while True:
if len(data) == 10:
break
time.sleep(.5)
data.append(random.randint(1, 200))
callback()
def wait_end(label, tk_var_end, num=0):
label["text"] = "Processing " + " ." * num
num += 1
if num == 4:
num = 0
if not tk_var_end.get():
mScrn.after(500, wait_end, label, tk_var_end, num)
def execute():
for entry in (tk_uid, tk_pwd, tk_ver):
entry['state'] = tk.DISABLED
tk_sub_button.destroy()
tk_process_lbl = tk.Label(mScrn)
tk_process_lbl.pack()
tk_process_lbl.place(x=150,y=150)
tk_var_end = tk.BooleanVar(False)
wait_end(tk_process_lbl, tk_var_end)
process = threading.Thread(
target=get_data,
kwargs=(dict(callback=lambda: tk_var_end.set(True)))
)
process.start()
mScrn.wait_variable(tk_var_end)
mScrn.after(500, tk_process_lbl.config, dict(text='Process completed'))
mScrn.after(1500, mScrn.quit)
mScrn = tk.Tk()
data = []
mScrn.title("Report Generation Tool v1.0")
mScrn.geometry("400x180")
mScrn.resizable(False, False)
tk_uid_lbl = tk.Label(mScrn, text="MVS1 Username")
tk_uid_lbl.pack()
tk_uid_lbl.place(x=20,y=20)
uid = tk.StringVar()
tk_uid = tk.Entry(mScrn, bd=3, textvariable=uid)
tk_uid.pack()
tk_uid.place(x=150, y=20)
tk_pwd_lbl = tk.Label(mScrn, text="MVS1 Password")
tk_pwd_lbl.pack()
tk_pwd_lbl.place(x=20,y=60)
pwd = tk.StringVar()
tk_pwd = tk.Entry(mScrn, bd=3, show='*', textvariable=pwd)
tk_pwd.pack()
tk_pwd.place(x=150, y=60)
tk_ver_lbl = tk.Label(mScrn, text="Version #")
tk_ver_lbl.pack()
tk_ver_lbl.place(x=20,y=100)
ver = tk.StringVar()
tk_ver= tk.Entry(mScrn, bd=3, textvariable=ver)
tk_ver.pack()
tk_ver.place(x=150, y=100)
tk_sub_button = tk.Button(text='Submit', command = execute)
tk_sub_button.pack()
tk_sub_button.place(x=150, y=150)
mScrn.mainloop()
print(data)
But, you can also make your own class which will inherit of Tk, in this class you could override the quit or destroy method of Tk.
Related
I just made a simple project with Tkinter GUI, but when I launch it and enter username, its window stops responding 'til the requests and instaloader processes are done, then it will be ok. Can I make a 'please wait' thing to avoid not responding? or does it get better if I migrate to another GUI?
from tkinter import *
import instaloader
from PIL import ImageTk, Image
import requests
from io import BytesIO
def insta(username):
L = instaloader.Instaloader()
profile = instaloader.Profile.from_username(L.context, username)
label2.config(text=profile.full_name)
label3.config(text=profile.biography)
url=profile.get_profile_pic_url()
response = requests.get(url)
img_data = response.content
img = ImageTk.PhotoImage(Image.open(BytesIO(img_data)))
panel = Label(image=img)
panel.place(x=150,y=100)
label4.config(text="Done")
window = Tk()
window.geometry("600x600")
window.maxsize(600, 600)
window.minsize(600, 600)
window.title("Instagram Profile Downloader")
# label
label = Label(window, text="Enter UserName to Download Profile Image:",
fg="black", bg="#f4b265")
label.place(x=180, y=20)
label2 = Label(window, text="")
label2.place(x=100, y=70)
label3 = Label(window, text="")
label3.place(x=100, y=100)
label4 = Label(window, text="", fg="red")
label4.place(x=380, y=50)
# button
def butt():
if input.get() == "":
label4.config(text="Please Enter Username")
return
else:
insta(input.get())
button = Button(window, text="Download", fg="white",
bg="#095e95", command=butt)
button.place(x=310, y=47)
# input
input = Entry(window)
input.place(x=180, y=50)
window.mainloop()
Tkinter stuff is running in the main thread and so when you call something in the main thread that takes time the GUI will be blocked while that function is running. To solve this you need to use threads to make sure the call to insta is running separate from the main thread where tkinter is running but also need to make sure that you dont call tkinter functions on that other thread because tkinter only works in the main thread.
Here's an exemple of how you could acheive it:
import threading
class InstaThread:
def __init__(self, username):
self.profile = None
self.img_data = None
# Disable the button while instaloader is running
button["text"] = "Loading..."
button["state"] = DISABLED
self.thread = threading.Thread(target=self.insta, args=(username,))
self.thread.start()
self.check_thread()
# Check periodically if the function has alread run
def check_thread(self):
if self.thread.is_alive():
window.after(100, self.check_thread)
else:
label2.config(text=self.profile.full_name)
label3.config(text=self.profile.biography)
panel = Label(window)
img = ImageTk.PhotoImage(Image.open(BytesIO(self.img_data)))
# Also updated this so that the image would really show in the panel
panel.image = img
panel.config(image = img)
panel.place(x=150,y=100)
label4.config(text="Done")
# Reset button
button["text"] = "Download"
button["state"] = NORMAL
# Function that will be running in other thread and updating the profile and img_data varibles of this class
def insta(self, username):
L = instaloader.Instaloader()
self.profile = instaloader.Profile.from_username(L.context, username)
url=self.profile.get_profile_pic_url()
response = requests.get(url)
self.img_data = response.content
Now in the Butt function you just need to call InstaThread(input.get()) instead of insta(input.get()) and like this when you click the button it will disable and say Loading while the function is running and the rest of the GUI will continue working fine
Another suggestion I have is for you to make a class for your GUI so that you have it all in one place and can access it anywhere inside the class so that you dont have to be having global variables for buttons and labels.
I would like to implement a very simple GUI for my project. I was previously using just Print statements to output some text and data. However, that is not very conveneint and since a person will need to operate a device that I am coding, he needs to be clearly see the instructions that I am going to display on GUI.
my code:
main()
myConnection = mysql.connector.connect( host=hostname, user=username, passwd=password, db=database )
counter = 0
window = tk.Tk()
window.title("GUI")
window.geometry("400x200")
while(1):
# OPERACIJOS KODAI:
# 0 - PILDYMAS
# 1 - KOMPLEKTAVIMAS
# 2 - NETINKAMAS KODAS
tk.Label(window,text = "Scan barcode here:").pack()
entry = tk.Entry(window)
entry.pack()
var = tk.IntVar()
button = tk.Button(window,text="Continue",command = lambda: var.set(1))
button.pack()
print("waiting...")
button.wait_variable(var)
result = entry.get()
print("Entry string=",result)
var.set(0)
operacijos_kodas=Scanning_operation(myConnection,result)
print("operacijos kodas=",operacijos_kodas)
if(operacijos_kodas == 0):
tk.label(window,text = "PILDYMO OPERACIJA:").pack()
pildymo_operacija(myConnection)
elif(operacijos_kodas == 1):
tk.Label(window,text = "PAKAVIMO OPERACIJA:").pack()
insertData_komplektacija(myConnection,"fmb110bbv801.csv");
update_current_operation(myConnection);
picking_operation();
elif(operacijos_kodas == 2):
print("Skenuokite dar karta")
#break
window.mainloop();
Nothing is being displayed. It just opens up an empty GUI window.
First of all, I am unsure where should I call function window.mainloop().
Secondly, since my system runs in an infinite while loop ( the operation starts when a user scans a bar-code, then he completes an operation and the while loop starts over again (waiting for user to scan a bar-code). So I just simply have to display some text and allow user to input data in the text box.
Could someone suggest me whether this GUI is suitable for my needs or I should look for an alternatives?
UPDATE*********************
I have tried to use mainloop:
print ("Using mysql.connector…")
main()
GPIO_SETUP()
myConnection = mysql.connector.connect( host=hostname, user=username, passwd=password, db=database )
counter = 0
window = tk.Tk()
window.resizable(False,False)
window_height = 1000
window_width = 1200
#window.attributes('-fullscreen',True)
#window.config(height=500,width=500)
#can = Canvas(window,bg='red',height=100,width=100)
#can.place(relx=0.5,rely=0.5,anchor='center')
window.title("GUI")
screen_width = window.winfo_screenwidth()
screen_height= window.winfo_screenheight()
x = int((screen_width/ 2) - (window_width / 2))
y = int((screen_height/ 2) - (window_height / 2))
window.geometry("{}x{}+{}+{}".format(window_width,window_height,x,y))
label1=Label(window,text = "SKENUOKITE BARKODA(GUID) ARBA DAIKTO RIVILINI KODA:")
label1.pack()
entry = Entry(window)
entry.pack()
var = tk.IntVar()
button = Button(window,text="Testi operacija",width = 30,command = lambda: var.set(1))
button.pack()
#button2 = Button(window,text="RESTARTUOTI SISTEMA",width = 30,command = restart_devices())
#button2.pack()
print("waiting...")
button.wait_variable(var)
Scanned_serial = entry.get()
print("Entry string=",Scanned_serial)
var.set(0)
label2=Label(window,text = "Vykdoma operacija:")
label2.pack()
window.update()
window.after(1000,Full_operation(Scanned_serial,label2,window))
window.mainloop()
This is my code. As you can see. i call Full_operation function and then window.mainloop()
my Full_operation:
def Full_operation(Scanned_serial,label2,window):
operacijos_kodas=Scanning_operation(myConnection,Scanned_serial)
print("operacijos kodas=",operacijos_kodas)
if(operacijos_kodas == 0):
label2.config(text = "SPAUSKITE MYGTUKA ANT DEZES KURIA NORITE PILDYTI:")#update the label2
window.update()#call update to update the label
pildymo_operacija(myConnection,Scanned_serial,label2,window)
elif(operacijos_kodas == 1):
insertData_komplektacija(myConnection,"fmb110bbv801.csv");
update_current_operation(myConnection);
#label2.config(text = "IMKITE DAIKTUS IS ZALIOS DEZUTES:")#update the label2
picking_operation(myConnection,label2);
elif(operacijos_kodas == 2):
print("Skenuokite dar karta")
label2.config(text = "NUSKENUOTAS NEGALIMAS KODAS:")#update the label2
window.update()#call update to update the label
How can I ensure that everytime I enter FUll_operation function I start from clean GUI again and start another operation.
Now I am able to complete operation once. After that, the GUI is not responsive.
I have added a print statement at the beggining of my full_operation and it does not execute after I complete it once so my mainwindow does not seem to work properly.
You'll need to adapt your code to work with a GUI. You can't introduce infinite loops in to tkinter GUI's without causing all sorts of problems.
Mainloop should only be called once.
I'd suggest that you move all of your scanning/saving operations in to a separate function which you schedule to occur periodically using the tkinter after method.
For example if you call your function scan you would schedule it to occur after 1 second using
root.after(1000, scan)
A more advanced method would be to have your scanning code running on a separate thread.
Also, you are currently trying to create the label each time you go round the while loop rather than just creating and packing them once and updating the text of the labels when you perform the "scanning". You can update the text of a label using the config method, for example
## Create a label
label1 = tk.Label(window,text = "PAKAVIMO OPERACIJA:")
##Pack the label
label1.pack()
## Update the text later
label1.config(text="New Text")
Here is an example of updating tkinter widgets periodically from a function.
import tkinter as tk
import random
def scanning():
num = random.randint(0,100)
entryTemperature.delete(0, tk.END) #Delete the current contents
entryTemperature.insert(0, f"{num} K") #Add new text
root.after(1000, scanning) #Schedule the function to run again in 1000ms (1 second)
root = tk.Tk()
entryTemperature = tk.Entry(root)
entryTemperature.grid(padx=50,pady=50)
root.after(1000, scanning)
root.mainloop()
I'm very new to python programming and I've been unable to find out how to get this to function properly. I'm using frames to show a login screen prior to loading the main inventory frame. I intend to record changes to inventory per user, so this is necessary for the program to function properly.
The program calls the Loginscreen() and LoginFrameGenerate() functions to generate the top menu and the frame including labels and entry fields. (Using Tkinter)
The "Log In" button, once pressed, calls the loginfun() function.
The loginfun() function is supposed to use an if statement to check the username and password and if they are correct, remove the login screen frame. Once the login screen frame has been removed, the mainframe and menu functions are called.
Unfortunately, the login screen frame will not go away when using the destroy() command. I can't move forward until I can get this working. Any guidance would be greatly appreciated.
I tried the function without re-initializing the frame inside the loginfun() function, but it generates a name error. I no longer get the name error, but the frame doesn't get destroyed. I've searched google and stack overflow for hours and the only thing I could find regarding Tkinter destroy() was in reference to classes. I'm beginning to think I've been coding this wrong and I should have made each frame a separate class.
from tkinter import *
import tkinter.messagebox
import sys
root = Tk()
root.iconbitmap('Favicon.ico')
testusername = "Admin"
testpassword = "Pass"
CurrentUser = StringVar()
Pass = StringVar()
root.state("zoomed")
def Exitbtnclick():
sys.exit(0)
def logout():
MainFrame=Frame(root)
MainFrame.destroy()
loginScreen
loginFrameGenerate
def loginScreen():
loginMenu = Menu(root)
root.configure(menu=loginMenu)
FileMenu=Menu(loginMenu)
loginMenu.add_cascade(label="File", menu=FileMenu)
FileMenu.add_cascade(label="Exit",command=Exitbtnclick)
def loginFrameGenerate():
#THIS CREATES THE LOGIN FRAME
logframe = Frame(root)
logframe.grid()
UL = Label(logframe, text="Username:", font="Arial 10 bold")
UL.grid(row=0, column=0, sticky="E")
UE = Entry(logframe, textvariable=CurrentUser)
UE.grid(row=0,column=1)
PL = Label(logframe, text="Password:", font="Arial 10 bold")
PL.grid(row=1, column=0, sticky="E")
PE = Entry(logframe, textvariable=Pass)
PE.grid(row=1,column=1)
loginbtn = Button(logframe, text="Log In", command=loginfun)
loginbtn.grid(row=3,columnspan=2)
def loginfun():
#THIS FUNCTION IS CALLED WHEN THE "LOG IN" BUTTON IS PRESSED
global testusername
global testpassword
logframe = Frame(root)
if (CurrentUser.get() == testusername) and (Pass.get() == testpassword):
logframe.destroy() #THIS IS THE PART THAT DOES NOT WORK
initializeMainMenu
initializeMainFrame
else:
tkinter.messagebox.showinfo("Error!", "Invalid Username/Password")
return
def initializeMainMenu():
mainMenu = Menu(root)
root.configure(menu=mainMenu)
FileMenu = Menu(mainMenu)
UserMenu = Menu(mainMenu)
ItemsMenu = Menu(mainMenu)
ReportMenu = Menu(mainMenu)
mainMenu.add_cascade(label="File", menu=FileMenu)
mainMenu.add_cascade(label="Users", menu=UserMenu)
mainMenu.add_cascade(label="Items", menu=ItemsMenu)
mainMenu.add_cascade(label="Reports", menu=ReportMenu)
FileMenu.add_separator()
FileMenu.add_command(label="Log Out/Switch User", command=logout)
FileMenu.add_command(label="Exit", command=Exitbtnclick)
UserMenu.add_command(label="Add/Remove Users",command=random)
def initializeMainFrame():
##Main Inventory Screen To Be Filled in once the user is logged in
MainFrame = Frame(root)
MainFrame.grid()
loginScreen()
loginFrameGenerate()
root.mainloop()
So my first GUI window is meant for taking input from user :
from tkinter import *
from main import *
root = Tk()
root.configure(background="orange")
root.wm_title("Python Project")
label_1 = Label(root, text="Project Name",bg="orange",fg="black")
label_2 = Label(root, text="Site URL Link",bg="orange",fg="black")
entry_1 = Entry(root)
entry_2 = Entry(root)
label_1.grid(row=0,sticky=W)
label_2.grid(row=3333,sticky=W)
entry_1.grid(row=0,column=1,padx=50,ipadx=100)
entry_2.grid(row=3333,column=1,ipadx=100)
def callback():
a1 = entry_1.get()
a2 = entry_2.get()
mmm(a1,a2,root) # main program
button1 = Button(root,text="Run",command=callback)
button2=Button(root,text="Quit",command=root.quit)
button1.grid(row=3334,ipadx=15,padx=50,column=1)
button2.grid(row=3335,column=1,ipadx=15,padx=50)
root.mainloop()
And then i use another GUI window someone in this forum made to show my results :
from tkinter import *
root = Tk()
textbox = Text(root)
textbox.pack()
def redirector(inputStr):
textbox.insert(INSERT, inputStr)
sys.stdout.write = redirector # whenever sys.stdout.write is called, redirector is called.
sys.stderr.write = redirector
root.mainloop()
Now every time i run the first GUI , both GUIs open although there is no way the code reached the second GUI code yet... What is the problem here?
Also the second GUI is supposed to print from a class , but i have a bunch of error when I try to just put it there . What changes I need to make so I can make this 2nd GUI work with a class?
I want to have a login window pop up at first, then once the conditions are satisfied, it closes the login window and opens a new window.
from Tkinter import *
import tkMessageBox
#Not really sure what i'm doing here anymore
while True:
Login = Tk()
Login.title('Login')
Login.geometry('400x130')
NameLabel = Label(Login, text='Username')
NameLabel.place(bordermode=OUTSIDE, height=25, width=100, x=100)
NameEntryRaw = Entry(Login)
NameEntryRaw.place(bordermode=OUTSIDE, height=25, width=100, x=200)
CodeLabel = Label(Login, text='Code')
CodeLabel.place(bordermode=OUTSIDE, height=25, width=100, x=100, y=30)
CodeEntryRaw = Entry(Login)
CodeEntryRaw.place(bordermode=OUTSIDE, height=25, width=100, x=200, y=30)
def tbd():
tkMessageBox.showinfo('Congrats!', 'This program is not done yet')
def login():
Usernames=list()
Usernames.append('Mordecai')
Usernames.append('Ezekiel')
Usernames.append('Goliath')
Usernames.append('Abraham')
Usernames.append('Bartholomew')
Usernames.append('Jedediah')
Usernames.append('Solomon')
Usernames.append('Tobias')
Usernames.append('Yohanan')
Usernames.append('Lucifer')
NameEntry=NameEntryRaw.get()
CodeEntry=CodeEntryRaw.get()
CodeReal='116987'
if Usernames.count(NameEntry) == 0:
tkMessageBox.showinfo('Error!', 'Your Username is invalid! Try Again.')
else:
()
if CodeEntry != CodeReal:
tkMessageBox.showinfo('Error!', 'The Code entered is invalid! Try Again.')
else:
()
LoginButton = Button(Login, text="Login", command=login)
LoginButton.place(bordermode=OUTSIDE, height=50, width=200, x=100, y=60)
Login.mainloop()
else:
DataBase = Tk()
#this will be the data base
DataBase.mainloop()
You don't want to use two mainloop's. Generally speaking, your tkinter app should have a single .mainloop called.
As for how to get the login popup and then switch to the window... You can create your root window with the app and when you start your program have a Toplevel window be shown with the login stuff, maybe hide / withdraw the root additionally?, have the toplevel have a submit button or something that would validate the credentials. If the credentials are valid, then you can use the destroy() method and remove the toplevel widget / go to the root window for your main app.
Having a while True repeat the process of creating a GUI + mainloop is bad for obvious reasons.
Edit: static is probably a bad term for a mutable object, since it's mutable... Added tuple vs list for global.
You don't need to create a blank list and then use append to add your usernames to the usernames list. You can make this global. Since, username is a mutable object (it's a list) you could still perform operations elsewhere in your code on this global, say .append etc. Or, if you never have these change i'd make it a tuple, since they're immutable and this "fits" better with the intent.
Instead of using .count(*) to get the occurrences of an element in a list you can just use:
if (object) in (some list) #Object is an abstraction, not the type
If CodeReal is static, which it looks to be, you can also make this global.
Here's a quick edit to your code, you can do this without classes, but I used classes here to try to distinctly show the logical separation in the program.
I changed a few variable names as well, so that it was easier to read / understand. I also used .pack() and .grid() as this was quicker to code than having to use .place() everywhere this is an arbitrary choice.
import Tkinter as tk
import tkMessageBox as messagebox
import sys
#No need to do usernames = list() and then .append for each one.
#Just make a global list holding them all...
USERNAMES = ('Mordecai', 'Ezekiel', 'Goliath', 'Abraham', 'Bartholomew',
'Jedediah', 'Solomon', 'Tobias', 'Yohanan', 'Lucifer')
PASSWORD = '116987' #Was CodeReal, this can be global
#We overrode the closing protocol here.
def closing_protocol():
if messagebox.askokcancel("Quit", "Do you want to quit?"):
sys.exit()
#A container for our Login "app".
class Login(tk.Toplevel):
def __init__(self, *args, **kwargs):
#We init the toplevel widget.
tk.Toplevel.__init__(self, *args, **kwargs)
#We set the closing protocol to be the overridden version / func.
self.wm_protocol("WM_DELETE_WINDOW", closing_protocol)
tk.Label(self, text='Username').grid(row=0, column=0)
self.username = tk.Entry(self)
self.username.grid(row=0, column=1)
tk.Label(self, text='Password').grid(row=1, column=0)
#Show = '*' just hides the password instead of plain-text like
#you typically see
self.password = tk.Entry(self, text='Password', show='*')
self.password.grid(row=1, column=1)
#When the button is clicked the _callback function will be called
tk.Button(self, text='Login', command=self._callback).\
grid(row=2, column=0, columnspan=2, sticky="nsew")
def _callback(self):
#If the username or password is bad, raise an error message.
if (self.username.get() not in USERNAMES or
self.password.get() != PASSWORD):
messagebox.showerror("Validation Error!",
"You have entered invalid credentials.\n" +
"Please try again.")
#otherwise, we're good to go. Destroy login / show main app.
else:
root.deiconify()
app.pack()
self.destroy()
class Main(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
tk.Label(self, text="MAIN APP STUFF").pack()
if __name__ == '__main__':
root = tk.Tk()
root.withdraw() #Hides the root window initially.
app = Main(root)
Login()
root.mainloop()
I want to thank you for clarifying what you did for me. It proved to be very helpful! Here is what I've settled with. I put the names back and made it to work without classes, as I found it a little too difficult to work with.
from Tkinter import *
import tkMessageBox
import sys
import binascii #Not for this part
Codenames = ['Mordecai', 'Ezekiel', 'Goliath', 'Abraham', 'Bartholomew',
'Jedediah', 'Solomon', 'Tobias', 'Yohanan', 'Lucifer']
Password = '116987'
def close_protocol():
if tkMessageBox.askokcancel("Quit", "Do you want to quit?"):
sys.exit()
#Below for a later part...
def text_to_bits(text, encoding='utf-8', errors='surrogatepass'):
bits = bin(int(binascii.hexlify(text.encode(encoding, errors)), 16))[2:]
return bits.zfill(8 * ((len(bits) + 7) // 8))
def text_from_bits(bits, encoding='utf-8', errors='surrogatepass'):
n = int(bits, 2)
return int2bytes(n).decode(encoding, errors)
def int2bytes(i):
hex_string = '%x' % i
n = len(hex_string)
return binascii.unhexlify(hex_string.zfill(n + (n & 1)))
#Above for a later part...
SDB = Tk()
SDB.title("SMEGJALBYT DATA BASE")
SDB.withdraw()
SDBLogin = Toplevel()
SDBLogin.title("Login")
SDBLogin.wm_protocol("WM_DELETE_WINDOW", close_protocol)
CodenameLabel = Label(SDBLogin, text="Codename")
CodenameLabel.grid(row=0, column=0)
CodenameEntry = Entry(SDBLogin)
CodenameEntry.grid(row=0, column=2)
PasswordLabel = Label(SDBLogin, text="Password")
PasswordLabel.grid(row=1, column=0)
PasswordEntry = Entry(SDBLogin, show='*')
PasswordEntry.grid(row=1, column=2)
def login_operation():
if CodenameEntry.get() not in Codenames:
tkMessageBox.showinfo("INVALID CODENAME!", "Please verify input in the 'Codename' field")
elif PasswordEntry.get() != Password:
tkMessageBox.showinfo("INVALID PASSWORD!", "Please verify input in the 'Password' field")
else:
SDB.deiconify()
SDBLogin.destroy()
LoginButton = Button(SDBLogin, text="Login", command=login_operation)
LoginButton.grid(row=2, column=1)
#Code continues...
#Code finisles....
SDB.mainloop()
This has the same basic functionality, just organised the way I wanted it.