1

The purpose of my program is to log keypresses in a text editor and display with a timer in real time. Functionality would be similar to manually opening a text editor and typing, which provides immediate feedback.

The code below logs keypresses to the text editor, but output only shows once the program finishes. How can I open the txt file and show keypresses and timer value in real time?

from tkinter import *
import time

import keyboard

root = Tk()
root.title('quick_data')

session_duration = IntVar()

def startSession():
    f = open("quick_data.txt", "a")
    for remaining in range(1, int(session_duration.get() + 1), +1):
        if (keyboard.is_pressed("a")):
            r = "{:2d} s".format(remaining) + " --> response 1"
        elif (keyboard.is_pressed("b")):
            r = "{:2d} s".format(remaining) + " --> response 2"
        else:
            r = "{:2d} s".format(remaining)
        f.write(r)
        f.write("\n")
        f.flush()
        time.sleep(1)

Label(root, text="Session duration").grid(row=1, sticky=W)
Entry(root, textvariable = session_duration).grid(row=1, column=1, sticky=E)

WSignUp = Button(root, text="Start Session", command=startSession).grid(row=3, column=0, sticky=W)
root.mainloop()
Alex Elfont
  • 115
  • 1
  • 12
  • 2
    why not just use Text widget? also why do You think the text doesn't show up, You are not even showing it unless You use notepad which is just a program, so it is a bit confusing but I suggest You just use `Text` widget – Matiiss May 10 '21 at 22:48
  • send text directly to widget. Because you run it in loop which never exit startSession so you will have to use `root.update()` to refresh window. Or you should write it in different way using `root.after()` instead of sleep - and with different loop. – furas May 10 '21 at 23:31

1 Answers1

1

You could use widget Text and write directly to widget.

When you run code in loop then it blocks tkinter. It waits for the end of function to update content in window. You need to use root.update() to force tkinter to update content in window.

from tkinter import *
import time
import keyboard

# --- functions ---  # PEP8: `lower_case_names` for functions

def start_session():
    
    for remaining in range(1, session_duration.get()+1, 1):
        
        if (keyboard.is_pressed("a")):
            r = "{:2d} s".format(remaining) + " --> response 1"
        elif (keyboard.is_pressed("b")):
            r = "{:2d} s".format(remaining) + " --> response 2"
        else:
            r = "{:2d} s".format(remaining)
            
        text.insert('end', r + '\n')
        root.update()
        
        time.sleep(1)

# --- main ---

root = Tk()
root.title('quick_data')

session_duration = IntVar(value=5)

Label(root, text="Session duration").grid(row=1, sticky=W)
Entry(root, textvariable = session_duration).grid(row=1, column=1, sticky=E)

WSignUp = Button(root, text="Start Session", command=start_session).grid(row=3, column=0, sticky=W)

text = Text(root)
text.grid(row=4, column=0, columnspan=2)

root.mainloop()
furas
  • 134,197
  • 12
  • 106
  • 148
  • Thanks for the response! I'm hoping to destroy the set timer window and open the text editor instead of having them in the same window. This updates the time but does not write text assigned to "a" or "b" keypresses – Alex Elfont May 13 '21 at 14:33
  • to write in editor you would have to open edit, wait short time (because editor may need time to open) and use `keyboard.send()` to send text to editor. But it may work only if editor is main/active window. It will not send to hidden editor. Besides usually editor doesn't have function to automatically update content in window when file is changed - so writing in file is rather useless. – furas May 13 '21 at 18:35