1

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() 
  • Not sure if it's the direct cause of the problem you're describing, but `user_name_input_area` will not be what you think it is. You're binding it to the result returned by some anonymous `tk.Entry` object's `place` method. You'll want to bind `user_name_input_area` to a `tk.Entry` instance in one statement, and then in another statement, place the widget. – Paul M. Mar 06 '21 at 12:04
  • As @PaulM. said `username_var` will always be `None`. [This](https://stackoverflow.com/q/66385003/11106801) person also had the same problem – TheLizzard Mar 06 '21 at 12:06
  • I would suggest you post all of your code. It's hard to tell what's going on without seeing more code. – Paul M. Mar 06 '21 at 12:07
  • Like this: ```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)``` Is that supposed to fix my problem? –  Mar 06 '21 at 12:08
  • Also you know that if you call `username_var.get()` immediately after creating `user_name_input_area` it will return `""` as the user hasn't had enough time to actually write anything there. – TheLizzard Mar 06 '21 at 12:08
  • I have posted my full code now. Some of it is not relevant to the question but you can ignore those bits. –  Mar 06 '21 at 12:12
  • @r_u_stalking_me You know that you have the exact same problem with `submit_button = Button(...).place(...)` and `Service` and `user_name`. – TheLizzard Mar 06 '21 at 12:22
  • I have changed the button thing now. I have also tried ```writeToFile(Service_input_area)``` but that writes: .!entry to the file before the password. –  Mar 06 '21 at 12:26

2 Answers2

1

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.

Paul M.
  • 10,481
  • 2
  • 9
  • 15
0

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

JacksonPro
  • 3,135
  • 2
  • 6
  • 29