user9566521
user9566521

Reputation:

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() 

Upvotes: 1

Views: 1785

Answers (2)

JacksonPro
JacksonPro

Reputation: 3275

This answer has already has pointed out most of the mistakes.

I also see a few more things that you are doing wrong specifically under isSubmit() function. Here you are creating 2 labels and a button that would be created whenever the submit button is pressed. you either need to destroy the previous label and buttons or create a label and button only once and use place() and place_forget() to show and hide them. Also, try to avoid using python inbuilt class and function names to name your variables.

Here is your corrected code:

import string
import random
from tkinter import * 

mypasslist = []

with open(r"file.txt", "r") as inp:
    for line in inp:
        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(r"file.txt", "a") as inp:
        inp.writelines(input_variable)

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

def ifSubmit():

    passwd = generatePassword()
    label1.config(text='Your password is: %s' % passwd)
    label1.place(x = 40, y = 170)

    label2.config(text='Your password and username has been saved, you can access them below.')
    label2.place(x = 40, y = 227)


    copy_button = Button(top, text = 'Copy', command=copyText).place(x=40, y=195)
    
    writeToFile(service_var.get()+', ')
    writeToFile(username_var.get()+', ')
    writeToFile(passwd+'\n')

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

# the label for user_name  
Label(top, text = "Service").place(x = 40, y = 60)   
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)

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


# label 1
label1 = Label(top, font=("Arial", 11))
label2 = Label(top, justify='left')

copy_button = Button(top, text = 'Copy', command=copyText)


top.mainloop() 

Upvotes: 0

Paul M.
Paul M.

Reputation: 10799

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.

Upvotes: 1

Related Questions