2

I am writing some GUI code with the tkinter module. My problem is that I want to read the entry input, without clicking a Button. So that the entry input is going to be written to a .txt file automaticly. for example: If I type in 'a' , the text file should be appended with the char 'a'

import tkinter as tk

def writefile():
    with open("/home/max/writeThings/name.txt", "a+") as f:
        f.writelines(name.get())
        print("File has been written !")
        root.update()
root = tk.Tk()

canvas = tk.Canvas(root,width = 800, height = 600)
canvas.pack()

frame = tk.Frame(root, bg = "yellow")
frame.place(relwidth = 1, relheight = 1)


name = tk.StringVar()

entry = tk.Entry(frame, textvariable = name, bg = "orange", font= "arial 18 ", justify = "center", fg = "black")
entry.place( relx = 0.25, rely = 0.05, relwidth = 0.5, relheight = 0.1)
entry.focus_set()

writefile()

root.mainloop()
Aditya
  • 533
  • 3
  • 11
JimmeyNeutron
  • 57
  • 1
  • 5
  • 1
    use `event` to that – AD WAN Jun 13 '19 at 16:38
  • What should happen if the user enters "abc"? Will the file contain "a" followed by "ab" followed by "abc", for a total of "aababc"? What should get written if the user enters "XYZ", then backspaces to delete "YZ", and then writes "QR"? – Kevin Jun 13 '19 at 16:46
  • Kevin , I just need the file to append text , I will fix the rest, I already have an idea. – JimmeyNeutron Jun 13 '19 at 16:50
  • Thus "abc" will result in "aababc". I just don't get it, how can the code "update" constantly my function. – JimmeyNeutron Jun 13 '19 at 16:55

2 Answers2

2

If you want some action to happen whenever the contents of an Entry widget changes, the most common solution is to associate a tkinter variable with the entry, and then put a trace on the variable -- a trace can call a function whenever a variable changes.

For example, start by adding this line after creating the name variable:

name.trace("w", writefile)

That will cause writefile to be called whenever the value changes.

When the trace calls the function it will pass along several variables. Your function doesn't use the variables but it needs to accept them, so modify the function signature to look like this:

def writefile(*args):

For more information about these arguments see What are the arguments to Tkinter variable trace method callbacks?

Finally, if you want the file to reflect what is in the entry widget (versus adding a new line every time the Entry is modified), you need to change the mode of the open statement to be w rather than a+ so that it overwrites the file with the new value each time it is called.

The final function should look like this:

def writefile(*args):
    with open("/home/max/writeThings/name.txt", "w") as f:
        f.writelines(name.get())
        print("File has been written !")

note: calling root.update() is completely pointless inside this function, as tkinter will automatically update once the function returns.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
2

Please refer the following code. You can use the writefile function with a slight modification as a callback for trace method in tk.StringVar.

Hope this helps.

import tkinter as tk


def writefile():
    with open("./name.txt", "r+") as f:
        f.truncate(0)
        f.writelines(name.get())
        print("File has been written !")
        root.update()

root = tk.Tk()

canvas = tk.Canvas(root, width = 800, height = 600)
canvas.pack()

frame = tk.Frame(root, bg = "yellow")
frame.place(relwidth = 1, relheight = 1)
frame.pack()

name = tk.StringVar()
name.trace("w", lambda l, idx, mode: writefile())
entry = tk.Entry(frame, textvariable = name, bg = "orange", font= "arial 18 ", justify = "center", fg = "black")
entry.place(relx = 0.25, rely = 0.05, relwidth = 0.5, relheight = 0.1)
entry.focus_set()
entry.pack()

root.mainloop()
Aditya
  • 533
  • 3
  • 11