[PYTHON] Iterative (recursive) processing with tkinter (displayed in order)

Goal When using python's tkinter for the first time, I created a program that displays English words in order, so I recorded it.

What is tkinter?

A library for generating GUI parts etc. with python. Can be installed with homebrew.

brew install tcl-tk

If you're using pyenv, you may have to uninstall-> reinstall the version of python you want to use after doing the above. I didn't work otherwise.

Iterative (recursive) processing

If you search on the Internet, you will often find implementation examples of count-up timers.

It is realized by changing the number inside the specified label (character or area part to be displayed) every second, and it should roughly use the following algorithms and functions.

class Timer
  def __init__(self):
    -Initialization of variables to count
    -Generate a label to display the number of the timer
    

  def count_up(label):
    -Display the value of the variable to be counted on the label
    -Increment of count
    -Count after 1 second_up()Call a function(Recursive) ---(*)

window = tkinter.Tk() #window generation
count_up_timer = Timer(window)
window.mainloop()

At (*), use tkinter's after () method. Call the specified function after the specified time with the name as it is.

In the following, the word is displayed instead of the number, or the display is stopped at a specific place.

A program that displays the entered English words in order

What did you make

The reason I chose this as an implementation theme is because I used a reading app called "Spritz". This app reads English sentences on web pages and displays them word by word like flash mental arithmetic.

Click here for Spritz From the research result that a considerable proportion of the time required to read a sentence is devoted to moving the viewpoint, it seems that the words are displayed in order in one place.

In short, I implemented this imitation using tkiner. (The head family has a lot of scientific ideas such as making one letter of each word red to make it easier to match the viewpoint.) Well, it may be a good practice to implement the restart function.

Implementation

I gave up the function to read the text of the web page. I will copy and paste the text into the text box. The UI looks like this.

tkinter_test.png

When you press the Start button,
The words in the text in the text box above are displayed one by one under the button. (You can see "Totoro" in the image.)

Code below

# import tkinter 
try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk
import time

class Flash:
    def __init__(self, parent, wpm, words_list, label):
        # variable storing time
        self.count = 0
        # label displaying words
        self.wpm = wpm
        self.words_list = words_list
        # convert wpm to display interval in ms
        self.wpm_interval = int(60/self.wpm * 1000)
        self.label = label
        # self.label = tk.Label(parent, text="***", font="Arial 40", width=25)
        self.label.pack()

    def display_next_word(self):
        # finish the loop when all words are displayed
        if self.count > len(self.words_list)-1:
            self.count = 0
            self.label.destroy()
            return

        # display next word
        self.label.configure(text="%s" % self.words_list[self.count])
        # increment the count
        self.count += 1

        # let tkinter to call self.refresh after 1/wpm sec
        self.label.after(self.wpm_interval, self.display_next_word)
        

if __name__ == "__main__":

    # define a window
    root = tk.Tk()
    root.geometry("400x300")

    # label for english sentences
    label_text = tk.Label(root, text=u'sentences (copy and paste):')
    label_text.pack()

    # text box for english sentences
    text = tk.Entry(root)
    text.pack()
    text.insert(tk.END, 'My Neighbor Totoro') # initial value

    # label for wpm (word per minutes)
    label_wpm = tk.Label(root, text=u'wpm \n (how many words you read/understand in 1 minutes):')
    label_wpm.pack()

    # text box for wpm
    wpm_box = tk.Entry(root)
    wpm_box.pack()
    wpm_box.insert(tk.END, '250')

    
    def start_flash():
        # prepare label for displayin words one by one
        label_flash_words = tk.Label(root, text="***", font="Arial 40", width=25)
        
        # prepare sentences and wpm values
        target_text = text.get()
        print("the number of words : ", len(target_text.split()))
        wpm_int = int(wpm_box.get())
        
        # start flashing
        flash = Flash(root, wpm = wpm_int, words_list = target_text.split(), label=label_flash_words)
        flash.display_next_word()
    
    start_btn = tk.Button(root, text='start', command=start_flash)
    start_btn.pack()
    
    root.mainloop()

The after method itself does not guarantee high time accuracy, so if you want it, you need to modify it separately.

Aside from the usefulness of the program itself, I learned about tkinter.

reference

RIP Tutorial, after

Recommended Posts

Iterative (recursive) processing with tkinter (displayed in order)
Processing order when chaining when in PySpark
Make a Spinbox that can be displayed in HEX with Tkinter
Easy image processing in Python with Pillow
How to use tkinter with python in pyenv
Parallel processing with no deep meaning in Python
MVC with Tkinter
Rewrite field order nodes in SPSS Modeler with Python.