Search code examples
pythonvariablestkintertextfile-writing

How do I get a variable from a text input in tkinter?


I have tried to get a variable from a text input by doing this:

username_var = StringVar()
user_name_input_area = Entry(top, width = 30, textvariable=username_var).place(x = 110, y = 100)
username = username_var.get()

However when I try to acess the variable in a function it does not do anything.

My two functions are:

def ifSubmit():
    writeToFile(service)
    writeToFile(username)

def writeToFile(input_variable):
    with open("password&usernames.txt", "a") as input:
        input.writelines(input_variable)

But when I open the text file, nothing appears. I have also tested with:

writeToFile('hello')

In this case I do get hello in my text file and so I suspect that it is the variables that is the probelm not the writeToFile() function.

So am I retrieving the text being inputed correctly?

Full code:

import string
import random
from tkinter import * 

mypasslist = []

with open("password&usernames.txt", "r") as input:
    for line in input:
        items = line.split()
        mypasslist.append([item for item in items[0:]])


def generatePassword():
    characters = string.ascii_letters + string.punctuation  + string.digits
    password =  "".join(random.choice(characters) for x in range(random.randint(8, 16)))
    return password

def writeToFile(input_variable):
    with open("password&usernames.txt", "a") as input:
        input.writelines(input_variable)

top = Tk()    
top.geometry("1920x1080")   

def ifSubmit():
    global a
    a = generatePassword()
    label1 = Label(top, text='Your password is: %s' % a, font=("Arial", 11)).place(x = 40, y = 170)
    label1 = Label(top, justify='left', text='Your password and username has been saved, you can access them below.').place(x = 40, y = 227)
    copy_button = Button(top, text = 'Copy', command=copyText).place(x=40, y=195)
    
    writeToFile(service)
    writeToFile(username)
    writeToFile(str(a))

def copyText():
    top.clipboard_clear()
    top.clipboard_append(a)
    top.update()

# the label for user_name  
Service = Label(top, text = "Service").place(x = 40, y = 60)   
user_name = Label(top, text = "Username").place(x = 40, y = 100)   

submit_button = Button(top, text = "Submit", command=ifSubmit).place(x = 40, y = 130) 

service_var = StringVar()
Service_input_area = Entry(top, width = 30, textvariable=service_var)
Service_input_area.place(x = 110, y = 60)
service = service_var.get()

username_var = StringVar()
user_name_input_area = Entry(top, width = 30, textvariable=username_var)
username = username_var.get()
user_name_input_area.place(x = 110, y = 100)

top.mainloop() 

Solution

  • A few things stick out:

    Let's say you're creating a label widget:

    label = Label(top, text="This is a label").place(x=40, y=40)
    

    This is incorrect. label will be bound to whatever the place method returned, because you're chaining the Label instantiation and the place method. The place method always returns None, so label will be None. You need to split this up into two separate statements - one to instantiate and bind the widget, the other to place it:

    label = Label(top, text="This is a label")
    label.place(x=40, y=40)
    

    You need to do this for every widget in your script, regardless of whether it's a label, button, etc.

    Also, in a few places, you do something like this:

    var = StringVar()
    entry = Entry(..., textvariable=var)
    user_input = var.get()
    

    Which is also incorrect. You create an entry widget, and then immediately read from it using var.get. Since you just created the widget, its contents will be empty, so in this case user_input will be empty. You also never change user_input, or read from the entry widget again at a later point, so what you end up writing to the file will just be an empty string. You need to call var.get once the user has actually had a chance to write something. A button callback would be a good place to do this.