Python Tkinter- Direct pointer back to Entry() box - python

When A user inputs a blank string of text I can either pop up a new input box which looks nasty or, like a webpage, direct the cursor back into the Entry() box
Unfortunately after searching I am still completely clueless as to how I can achieve this direction of the cursor.
My code looks like this-
import time
from tkinter import *
root = Tk()
##Encrypt and Decrypt
Master_Key = "0123456789 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#£$%&'()*+,-./:;?#[\\]^_`{|}~\t\n\r\x0b\x0c"
def Encrypt(User_Input, Key):
Output = ""
for i in range(len(User_Input)):
Ref_For_Output = Master_Key.index(User_Input[i]) + Master_Key.index(Key[i])
if Ref_For_Output >= len(Master_Key):
Ref_For_Output -= len(Master_Key)
Output += Master_Key[Ref_For_Output]
return Output
def Decrypt(User_Input, Key):
Output = ""
for i in range(len(User_Input)):
Ref_For_Output = Master_Key.index(User_Input[i]) - Master_Key.index(Key[i])
if Ref_For_Output < 0:
Ref_For_Output += len(Master_Key)
Output += Master_Key[Ref_For_Output]
return Output
##def popup():
## main = Tk()
## Label1 = Label(main, text="Enter a new key: ")
## Label1.grid(row=0, column=0)
## New_Key_Box = Entry(main, bg="grey")
## New_Key_Box.grid(row=1, column=0)
##
## Ok = Button(main, text="OK", command=Set_Key(New_Key_Box.get()))
##
## Ok.grid(row=2, column=0)
## if
## main.geometry("100x300")
## main.mainloop()
## return New_Key_Box.get()
class MyDialog:
def __init__(self, parent):
top = self.top = Toplevel(parent)
Label(top, text="Value").pack()
self.e = Entry(top)
self.e.pack(padx=5)
b = Button(top, text="OK", command=self.ok)
b.pack(pady=5)
def ok(self):
print( "value is" + self.e.get())
return self.e.get()
self.top.destroy()
def Compatibility(User_Input, Key):
while Key == "":
root = Tk()
Button(root, text="Hello!").pack()
root.update()
d = MyDialog(root)
print(d.ok(Key))
root.wait_window(d.top)
Temp = 0
while len(Key) < len(User_Input):
Key += (Key[Temp])
Temp += 1
return Key
##Layout
root.title("A451 CAM2")
root.geometry("270x80")
Label1 = Label(root, text="Input: ")
Label1.grid(row=0, column=0, padx=10)
Label2 = Label(root, text="Key: ")
Label2.grid(row=1, column=0, padx=10)
Input_Box = Entry(root, bg="grey")
Input_Box.grid(row=0, column=1)
Key_Box = Entry(root, bg="grey")
Key_Box.grid(row=1, column=1)
def Encrypt_Button_Press():
User_Input = Input_Box.get()
Key = Compatibility(User_Input, Key_Box.get())
print(User_Input)
root.clipboard_append(Encrypt(User_Input, Key))
Encrypt_Button.configure(text="Encrypting")
messagebox.showinfo("Complete", "Your encrypted text is: \n" + Encrypt(User_Input, Key) + "\n The text has been added to your clipboard.")
Encrypt_Button.configure(text="Encrypt")
#popup()
def Decrypt_Button_Press():
User_Input = Input_Box.get()
Key = Key = Compatibility(User_Input, Key_Box.get())
print(User_Input)
root.clipboard_append(Decrypt(User_Input, Key))
Decrypt_Button.configure(text="Decrypting")
messagebox.showinfo("Complete", "Your Decrypted text is: \n" + Decrypt(User_Input, Key) + "\n The text has been added to your clipboard.")
Decrypt_Button.configure(text="Decrypt")
Encrypt_Button = Button(text="Encrypt", command=Encrypt_Button_Press)
Encrypt_Button.grid(row=0, column=3, padx=10)
Decrypt_Button = Button(text="Decrypt", command=Decrypt_Button_Press)
Decrypt_Button.grid(row=1, column = 3, padx=10)
root.mainloop()
In the compatibility function I am wanting to change the while Key == "":
to pop-up a message (that's easy) and to direct the cursor back to the Key_Box( I may also make it change to red or something)
So- does anyone know how I can achieve redirection of the cursor?
Edit:I am not sure whether this is included anywhere in Tkinter, I can use tab to switch between Entry() boxes so I assume that they function in roughly the same way as other entry boxes across different platforms.

You could call .focus() on the entry? It won't move the cursor, but the user would be able to just start typing away in the entry box as if they had clicked in it.

Related

How do you use .get() with a multiframe shopping cart in python tkinter?

In this code. I want display the information from the frame I hit the Buy button on. I'm sure it is a simple solution but it has eluded me. I've been going through google and stack overflow with no solution yet.
I tried making the NewFrame global but that just does the last one made.
from tkinter import *
root = Tk()
FrameNum = 1
ItemCount = 1
def combine_funcs(*funcs):
def combined_func(*args, **kwargs):
for f in funcs:
f(*args, **kwargs)
return combined_func
def place_order():
global ItemCount
Product = Product_Box.get()
Label(root, text="Your Purchase of " + str(Product) + " Placed").grid(row=1, column=3, stick="w")
ItemCount += 1
def create_frame():
global FrameNum
NewFrame = LabelFrame(root,name=("newframe"+str(FrameNum)), text=("Item "+str(FrameNum)),width=100, height=100)
NewFrame.grid(row=FrameNum, column=0)
Product_Lab = Label(NewFrame, text="Product").grid(row=0, column=0)
Qty_Lab = Label(NewFrame, text="Qty").grid(row=0, column=1)
Price_Lab = Label(NewFrame, text="Price").grid(row=0, column=2)
# Entry Boxes
Product_Box = Entry(NewFrame, width=10).grid(row=1, column=0)
Qty_Box = Entry(NewFrame, width=12).grid(row=1, column=1)
Price_box = Entry(NewFrame, width=6).grid(row=1, column=2)
Remove_Bet_Button = Button(NewFrame, text="Del", command=NewFrame.destroy).grid(row=3, column=2)
Buy_Button = Button(NewFrame, text="Buy", command=combine_funcs(place_order, NewFrame.destroy)).grid(row=3, column=0)
FrameNum += 1
framebutton = Button(root, text="Frame", command=create_frame).grid(row=0, column = 3, stick ="n")
root.mainloop()
I get this error when hitting the Buy button. (with or without information entered into the boxes from that frame)
NameError: name 'Product_Box' is not defined
Product_Box is local variable created in create_frame() - to access it in other functions you have to assign to global variable - so you need add global Product_Box in create_frame()
But there is other problem:
variable = tk.Widget().grid() assigns None to variable because grid()/pack()/place() returns None. You have to do it in two steps variable = tk.Widget() and varaible.grid().
Product_Lab = Label(NewFrame, text="Product")
Product_Lab.grid(row=0, column=0)
And now code works but later you will have the same problem with other variables.
Full working code with other changes
PEP 8 -- Style Guide for Python Code
import tkinter as tk # PEP8: `import *` is not preferred
# --- functions ---
def place_order(product_box, qty_box, price_box, new_frame):
global item_count
global label
product = product_box.get()
qty = int(qty_box.get())
price = int(price_box.get())
total = qty * price
if not label:
label = tk.Label(root)
label.grid(row=1, column=3, stick="w")
# replace text
#label['text'] = f"Your Purchase of {product} Placed. (Qty: {qty}, Price: {price}, Total: {total})"
# or append in new line
if len(label['text']) > 0:
label['text'] += "\n"
label['text'] += f"Your Purchase of {product} Placed. (Qty: {qty}, Price: {price}, Total: {total})"
item_count += 1
new_frame.destroy()
def create_frame():
global frame_number
new_frame = tk.LabelFrame(root, name=f"newframe {frame_number}", text=f"Item {frame_number}", width=100, height=100)
new_frame.grid(row=frame_number, column=0)
tk.Label(new_frame, text="Product").grid(row=0, column=0)
tk.Label(new_frame, text="Qty").grid(row=0, column=1)
tk.Label(new_frame, text="Price").grid(row=0, column=2)
# Entry Boxes
product_box = tk.Entry(new_frame, width=10)
product_box.grid(row=1, column=0)
qty_box = tk.Entry(new_frame, width=12)
qty_box.grid(row=1, column=1)
price_box = tk.Entry(new_frame, width=6)
price_box.grid(row=1, column=2)
tk.Button(new_frame, text="Del", command=new_frame.destroy).grid(row=3, column=2)
tk.Button(new_frame, text="Buy", command=lambda:place_order(product_box, qty_box, price_box, new_frame)).grid(row=3, column=0)
frame_number += 1
# --- main ---
frame_number = 1
item_count = 1
root = tk.Tk()
tk.Button(root, text="Frame", command=create_frame).grid(row=0, column=3, stick="n")
label = None # it will add later but only once
root.mainloop()

Updating Tkinter text with label

I'm trying to make a GUI version of a drinking game, which involves throwing dice. I 'throw the dice' virtually, but want to display the outcome on the screen. I thought using Label() would be most useful, but i'm having trouble updating that text (the throw_text variable) when a new dice throw is done.
Instead of the text updating on the screen, a new text appears below the previous one with the new throw.
I don't want a cascading stream of text, but just one singular text that updates at the dice being thrown i.e. when the 'Roll!' button is pressed.
I've seen people do it using the Stringvar(), however i must be doing it wrong as it does not have an effect on the appearance.
from tkinter import *
dim = [900, 600]
root = Tk()
root.geometry(f"{dim[0]}x{dim[1]}")
root.title("Mex")
root.iconbitmap("dice.ico")
lbl = Label(root, font=("Times", 200))
num = ['\u2680', '\u2681', '\u2682', '\u2683', '\u2684', '\u2685']
d1 = None
d2 = None
throw_txt = StringVar()
def roll_dice():
global d1, d2
d1 = random.choice(num)
d2 = random.choice(num)
lbl.config(text=f"{d1}{d2}")
lbl.pack()
lbl.place(x=dim[0] / 3.8, y=50)
print("Throw:", check_throw(convert_symbol()))
throw_txt = str(check_throw(convert_symbol()))
txt = Label(root, text=throw_txt)
txt.pack(side=TOP)
def convert_symbol():
d1_num = None
d2_num = None
for n in num:
if n == d1:
d1_num = num.index(n) + 1
if n == d2:
d2_num = num.index(n) + 1
if d2_num > d1_num:
throw = f"{d2_num}{d1_num}"
else:
throw = f"{d1_num}{d2_num}"
return throw
def check_throw(t):
num_t = int(t)
if num_t == 21:
return "Mex"
elif num_t % 11 == 0:
return f"Koning: {int(num_t / 11 * 100)}"
elif num_t % 31 == 0:
return "Slok uitdelen"
else:
return str(num_t)
roll_btn = Button(root, text="Roll!", width=10, command=roll_dice)
roll_btn.config(font=("Bahnschrift", 20))
roll_btn.pack()
roll_btn.place(x=dim[0] / 2.5, y=25)
roll_btn = Button(root, text="Convert", width=10, command=convert_symbol)
roll_btn.config(font=("Bahnschrift", 20))
roll_btn.pack()
roll_btn.place(x=dim[0] / 2.5, y=500)
root.mainloop()
You could use the configure attribute instead of storing the text of the Label widget into a separate variable.
Take a quick look at this code:
from tkinter import *
root = Tk()
root.title("my game")
def change_text():
mylabel.configure(text="You just hit the button!")
mylabel = Label(root, text="Hit the button pls")
mylabel.grid(column=0, row=1, sticky='w')
mybutton = Button(root, text="Click me", command=change_text)
mybutton.grid(column=0, row=2, sticky='w')
root.mainloop()

How to create a counter for the number of times a button that was created was pressed in tkinter?

So I have made a simple program that allows me to type a label for a button and have it created and clickable in the tkinter gui. Now all I need is to add a function that returns the number of times each individual button is clicked. The problem is that the buttons I created are not actually coded in the input so I've found it difficult to do this. I feel like I would have to use the lambda function but I have no experience at all with it. Help is appreciated, thank you.
Code:
import tkinter as tk
from tkinter import *
window = tk.Tk()
window.title("Tkinter FINAL")
window.geometry("600x400")
window.resizable(width=False, height=False)
WIDTH = 800
HEIGHT = 600
counter_name = tk.Label(window, text="Counter Word", width=20)
counter_name.place(x=460,y=318)
counter_entry = tk.Entry(window, width=20)
counter_entry.place(x=470,y=338)
position_x = 0
position_y = 0
word_dict = {}
def button_function():
word_dict[title] += 1
button_count = 0
def button_maker():
global position_x, position_y, button_count, title
button = tk.Button(window, text=counter_entry.get(), width=10, height=2, command = button_function, fg="red")
button.place(x=position_x,y=position_y)
position_x += 116
button_count += 1
if button_count % 6 == 0:
position_y += 50
position_x = 0
title = counter_entry.get()
word_dict[title] = 0
counter_entry.delete(0,'end')
btnmaker = tk.Button(window, text='Click to create counter', width=17, height=2, command = button_maker, fg="red")
btnmaker.place(x=470,y=358)
btnreset = tk.Button(window, text='RESET', width=10, height=2, command = window.destroy, fg="red")
btnreset.place(x=520,y=500)
window.mainloop()
You need to pass the word entered to button_function() using lambda:
word_dict = {}
def button_function(word):
word_dict[word] += 1
print(word, word_dict[word])
def button_maker():
# get the input word
word = counter_entry.get().strip()
# make sure the input word is unique in the dictionary
if word and word not in word_dict:
count = len(word_dict)
button = tk.Button(window, text=word, width=10, height=2, fg="red",
command=lambda w=word: button_function(w)) # pass the input word to button_function()
button.place(x=count%5*116, y=count//5*60)
word_dict[word] = 0 # init the counter for the input word
counter_entry.delete(0,'end')
Updated code with counter labels:
word_dict = {}
def button_function(word):
count = word_dict[word].get()
word_dict[word].set(count+1)
def button_maker():
word = counter_entry.get().strip()
if word and word not in word_dict:
count = len(word_dict)
row, col = count//5*2, count%5
# create the word button
button = tk.Button(window, text=word, width=10, height=2, fg="red",
command=lambda w=word: button_function(w))
button.grid(row=row, column=col, padx=10, pady=(10,0))
# create the corresponding counter label
var = tk.IntVar() # for the counter value
tk.Label(window, textvariable=var).grid(row=row+1, column=col)
word_dict[word] = var
counter_entry.delete(0, 'end')

Tkinter problem creating button to collect text from user

I am new to Tkinter, and am trying to create a hangman app. I have already created a command-line version, so I thought it would be a nice beginning project. When learning I was told to use window.mainloop() for creating/updating, but my program contains a while loop, and so that hasn't worked. I am not able to type into the textbox i have created at all and when I click the button, it gives me a NameError saying textEntry in my click() method is not defined. Any help or guidance of where else to look would be much appreciated. Thanks! My code is posted below
from tkinter import *
from random import choice
def click():
guess = textEntry.get()
return guess
def main():
input_file = open('hangman_word_list.txt','r')
word_list = input_file.read().split()
window = Tk()
window.title("Play Hangman!")
window.configure(background="black")
p1 = PhotoImage(file='h1.gif')
p2 = PhotoImage(file='h2.gif')
p3 = PhotoImage(file='h3.gif')
p4 = PhotoImage(file='h4.gif')
p5 = PhotoImage(file='h5.gif')
p6 = PhotoImage(file='h6.gif')
Label(window,image=p1,bg="purple").grid(row=0,column=0,columnspan=4)
word = choice(word_list)
correctList = list(word)
lettersLeft = len(word)
hiddenWord = ('*' * lettersLeft)
wrongGuessList = []
lives = 6
again = True
nowPhoto = p1
guess = 'empty'
while lettersLeft > 0 and again == True:
Label(window,text="Your word is "+hiddenWord ,bg="gray",fg="purple",font="none 12 bold").grid(row=1,column=0,sticky=W)
Label(window,text="Enter a letter: " ,bg="gray",fg="purple",font="none 12 bold").grid(row=2,column=0,sticky=W)
textEntry = Entry(window,width=5,bg="white")
textEntry.grid(row=2,column=1,sticky=W)
guess = Button(window,text="Guess",width=5,command=click).grid(row=3,column=2,sticky=W)
window.update()
main()
The mainloop() listens continously for any hook that you have defined, which means you don't have to worry about that. Just define the right hooks, like the button command.
I introduced a nicer way to handle the images by putting them in a list and then reducing the list for each image requested. This makes it easier to update the image.
Then put all processing, like checking if a uessed letter is in the word etc. in the click() function.
from tkinter import *
window = Tk()
# Make a list of all the pictures
pic_list = ['h6.gif','h5.gif','h4.gif','h3.gif','h2.gif','h1.gif']
img = PhotoImage(file=pic_list.pop()) # Get image from list of images
hangman = Label(window, image=img) # Save reference to the Label as
hangman.grid(row=0,column=0,columnspan=4) # you will update it later
# I simplified the word selection a bit
word = 'Wensleydale'
correctList = list(word)
lettersLeft = len(word)
hiddenWord = ('*' * lettersLeft)
wrongGuessList = []
guess = 'empty'
# Build the rest of the GUI
Label(window,text="Your word is " + hiddenWord, bg="gray", fg="purple",
font="none 12 bold").grid(row=1, column=0, sticky=W, columnspan=4)
Label(window,text="Enter a letter: ", bg="gray", fg="purple",
font="none 12 bold").grid(row=2, column=0, sticky=W)
textEntry = Entry(window, width=10, bg="white")
textEntry.grid(row=2, column=1, sticky=W, columnspan=3)
def click(): # Callback function
guess = textEntry.get()
# Put all other processing here.
# Updating the image
img = PhotoImage(file=pic_list.pop()) # Get next image from list
hangman.configure(image=img) # Replace image in label
hangman.image = img # Keep reference to the new image
# Create button and associate it with the command callback function
guess_button = Button(window, text="Guess", width=5,
command=click).grid(row=3, column=2, sticky=W)
window.mainloop() # Will loop continously listening for buttonpress
Firstly, a while loop is not recommended for use when it comes to using tkinter module as the window would be running on the main thread. Logically, when using buttons, you can use if statements so that it won't trigger a specific part of code until lettersLeft > 0 and again == True. And the use of variable textEntry in a function is obviously not available to Python because there is no declaration of it. So you either pass the variable as argument or declare a global variable.
Here is what I would think of:
from tkinter import *
from random import choice
def get_wordlist():
return open("Hangman word list.txt", 'r').read().split("split by something here.")
class Hangman(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master.title("Hangman")
self.master.configure(bg="black")
self.wordlist = get_wordlist()
self.p1 = PhotoImage(file="h1.gif")
self.word = choice(self.wordlist)
self.hidden_word = list("".join("_" for x in word))
self.wrong_guess = []
self.lives = 6
self.word_display = Label(window, text=str(*(hidden for hidden in hidden_word)), image=p1, bg="purple", fg="white")
self.word_display.grid(row=0, column=0, columnspan=4)
Label(window, text="Enter a letter: ", bg="gray", fg="purple", font="none 12 bold").grid(row=2, column=0, sticky=W)
self.entry = Entry(window, width=5, bg="white")
self.entry.grid(row=2, column=1, sticky="W")
self.guess = Button(window, text="Guess", command=lambda: button_action(self))
self.guess.grid()
self.again = False
def button_action(self):
user_input = self.entry.get()
if len(user_input) == len(word):
for i in range(len(word)):
if word[i] == user_input[i]:
self.hidden_word[i] = word[i]
if "_" not in self.hidden_word:
self.word_display.config(text="You won! The correct word was: " + self.word)
self.after(3000, self.quit())
else:
self.word_display.config(text="Guess not correct! " + str(*(hidden for hidden in hidden_word)))
self.lives -= 1
else:
self.word_display.config(text="Guess not correct! " + str(*(hidden for hidden in hidden_word)))
self.lives -= 1
if self.lives <= 0:
self.word_display.config(text="You lost! The correct word was: " + self.word)
self.master.after(3000, self.quit())
Please note 2 things:
Try not to create redundant variables
Before even asking a question, please do look on python tkinter docs.

Python Tkinter error: "Label has no __call__method"

Im trying to create a Python tkinter login registeration but running into a small issue.
The error message is:
self.Label_Name = Label(top, text="What is your username: ")
AttributeError: Label instance has no __call__ method
Please can you proof read my code:
from Tkinter import *
class Register:
def __init__(self, parent):
top = self.top = Toplevel(parent)
# Variables to store the entries
self.VarEntUser = StringVar()
self.VarEntPass = StringVar()
self.VarEntRetype = StringVar()
self.Label_Name = Label(top, text="What is your username: ")
self.Label_Password = Label(top, text="Enter a password: ")
self.Label_Retype = Label(top, text="Retype Password: ")
# Entry fields for the user to enter there details
self.Ent_Name = Entry(top, textvariable=self.VarEntUser)
self.Ent_Password = Entry(top, textvariable=self.VarEntPass)
self.Ent_Retype = Entry(top, textvariable=self.VarEntRetype)
# Puts all the fields ^, into the window
self.Label_Name.grid(row=0, sticky=W)
self.Label_Password.grid(row=1, sticky=W)
self.Label_Retype.grid(row=2, sticky=W)
self.Ent_Password.grid(row=1, column=1)
self.Ent_Retype.grid(row=2, column=1)
self.Ent_Name.grid(row=0, column=2)
# Run the RegisterCheck function
# submit button which Checks the Entered details then writes the user and pass to a .txt file
self.MySubmitButton = Button(top, text='Submit', command=RegisterCheck)
self.MySubmitButton.pack()
self.U = raw_input(self.VarEntUser.get())
self.P = raw_input(self.VarEntPass.get())
self.R = raw_input(self.VarEntRetype.get())
class LogIn:
def __init__(self, parent):
top = self.top = Toplevel(parent)
self.a = StringVar()
self.b = StringVar()
self.Label_Log_User1 = Label(top, text='Username:')
self.Label_Log_Pass = Label(top, text='Password: ')
self.Ent_User_Log = Entry(top, textvariable=self.a)
self.Ent_Pass_Log = Entry(top, textvariable=self.b)
self.Label_Log_User1.grid(row=1)
self.Pass_Log.grid(row=2)
self.EntUserLog.grid(row=1, column=1)
self.EntPassLog.grid(row=2, column=1)
self.User = raw_input(self.EntUserLog.get())
self.Pass = raw_input(self.EntUserLog.get())
# runs the 'LoginCheck' function
self.LogInButton = Button(top, text="Log In", command=LogInCheck)
self.LogInButton.pack()
def LogInCheck(self):
# Checks if the fields are blanking displaying an error
if len(self.User) <= 0 and len(self.Pass) <= 0:
print "Please fill in all fields."
else:
pass
# Checks to see if the user and pass have been created
if self.User in 'username.txt' and self.Pass in 'password':
print 'You are now logged in!'
else:
print "Log in Failed"
def RegisterCheck(self):
# Checks if the fields are blank
if len(self.P) <= 0 and len(self.U) <= 0:
print "Please fill out all fields."
else:
pass
# Check is the password and the retype match
if self.P == self.R:
pass
else:
print "Passwords do not match"
# After registering write the user and pass to a .txt file
with open('username.txt', 'a') as fout:
fout.write(self.U + '\n')
with open('password.txt', 'a') as fout:
fout.write(self.P + '\n')
# Depending on what the user chooses, either log in or register than opens the specific window
def launch_Register():
inputDialog = Register(root)
root.wait_window(inputDialog.top)
def launch_LogIn():
inputdialog2 = LogIn(root)
root.wait_window(inputdialog2.top)
root = Tk()
label = Label(root, text='Choose an option')
label.pack()
loginB = Button(root, text='Log In', command=launch_LogIn)
loginB.pack()
registerB = Button(root, text='Register', command=launch_Register)
registerB.pack()
root.mainloop()
The problem is that in this line
Label = Label(root, text='Choose an option')
you define a Label called Label, thus shadowing the Label constructor. Then, then you create the several labels in your Register and Login classes (triggered by those two buttons), the name Label is no longer bound to the constructor, but to that specific label.
Change the name of the label, then it should work. Also, I would advise you to use lower-case names for variables and methods. This alone might help prevent many such errors.
root = Tk()
label = Label(root, text='Choose an option')
label.pack()
loginB = Button(root, text='Log In', command=launch_LogIn)
loginB.pack()
registerB = Button(root, text='Register', command=launch_Register)
registerB.pack()
root.mainloop()
Note that there are a few many more problems with your code:
StringVar a and b should probably be self.a and self.b
You are trying to use raw_input to get the user input in the Entry widgets; this is wrong! Instead, just read the value of the variables to get the values, e.g. instead of self.User, use self.a.get()
do not mix grid and pack layout
if self.User in 'username.txt' will not check whether that name is in that file
loginCheck and registerCheck should be methods of the respective class
Once I'm at it, here's (part of) my version of your code, to help you getting started:
class Register:
def __init__(self, parent):
top = self.top = Toplevel(parent)
self.var_user = StringVar()
self.var_pass = StringVar()
self.var_retype = StringVar()
Label(top, text="What is your username: ").grid(row=0, sticky=W)
Label(top, text="Enter a password: ").grid(row=1, sticky=W)
Label(top, text="Retype Password: ").grid(row=2, sticky=W)
Entry(top, textvariable=self.var_user).grid(row=0, column=1)
Entry(top, textvariable=self.var_pass).grid(row=1, column=1)
Entry(top, textvariable=self.var_retype).grid(row=2, column=1)
Button(top, text='Submit', command=self.registerCheck).grid(row=3)
def registerCheck(self):
u, p, r = self.var_user.get(), self.var_pass.get(), self.var_retype.get()
if p and u:
if p == r:
logins[u] = p
else:
print "Passwords do not match"
else:
print "Please fill out all fields."
class LogIn:
# analogeous to Register; try to figure this out xourself
def launch_Register():
inputDialog = Register(root)
root.wait_window(inputDialog.top)
def launch_LogIn():
inputDialog = LogIn(root)
root.wait_window(inputDialog.top)
logins = {}
root = Tk()
Label(root, text='Choose an option').pack()
Button(root, text='Log In', command=launch_LogIn).pack()
Button(root, text='Register', command=launch_Register).pack()
root.mainloop()
Note that I changed the login "database" from files to a dictionary to keep things simple and to focus on the Tkinter problems. Of course, neither a simple dictionary nor a plain-text file is an appropriate way to store login information.
Also, I put the creation and the layout of the GUI widgets on one line. In this case this is possible since we do not need a reference to those widgets, but beware never to do e.g. self.label = Label(...).grid(...), as this will bind self.label to the result of grid, and not to the actual Label.
Finally, this will still print all the messages to the standard output. Instead, you should add another Label for that, or open a message dialogue, but this is left as an excercise to the reader...

Categories