Periodic execution processing when using tkinter [Python3]

Overview

The following two methods are shown for periodic execution processing in tkinter.

--When using the threading module --When using the schedule module

For simple processing, you do not need to use the threading module or schedule module, but for heavy processing, the operation of tk itself (pressing a button / moving the screen, etc.) becomes heavy. Therefore, even if it is troublesome, it may be better to implement it by the above method.

When using the threading module

Below is the sample code. It is a program that increases the value of "self.label" by 1. If you want to do it, you can execute it regularly in milliseconds. Since it is python, the time accuracy is not so good, but if you do not have to worry about the time accuracy so much, this is enough.

import tkinter as tk
import threading

class GUI(tk.Frame):
    def __init__(self,master = None):
        super().__init__(master)
        self.master = master
        master.geometry("300x300")
        master.title("Test")
        
        self.count = 0 #Buffer of values defined in label
        
        self.test = tk.Frame(self.master)#It's not necessary, but I have created another frame to manage the screen.
        self.test.pack()
        self.label = tk.Label(self.test)
        self.label.pack()
        self.label["text"] = str(self.count) #Initialize label value
        
        self.timeEvent()#Timer start
        
    #Timer activation function
    def timeEvent(self):
        th = threading.Thread(target=self.update)#Thread instantiation
        th.start()#Thread start
        self.after(1000, self.timeEvent)#Now call the function recursively
        
    #Thread processing entity
    def update(self):
        self.count += 1
        print(self.count) #Debug message
        self.label["text"] = str(self.count) #Update label value

if __name__ == "__main__":
    gui = tk.Tk()
    app = GUI(master = gui)
    app.mainloop()

If you want more time accuracy, the process will be a little complicated, but you can write as follows. I think it will be twice as accurate in time, but it will be a little less readable.

import tkinter as tk
import threading
import time

class GUI(tk.Frame):
    def __init__(self,master = None):
        super().__init__(master)
        self.master = master
        master.geometry("300x300")
        master.title("Test")
        
        self.count = 0
        
        self.test = tk.Frame(self.master)
        self.test.pack()
        self.label = tk.Label(self.test)
        self.label.pack()
        self.label["text"] = str(self.count)
        self.buftime = time.time()#Timer initialization
        self.timeEvent()
    
    
    def timeEvent(self):
        tmp = time.time()
        if(tmp - self.buftime) >= 1: #When 1 sec has passed
            th = threading.Thread(target=self.update)
            th.start()
            print(tmp - self.buftime)
            self.buftime = tmp
        self.after(1, self.timeEvent)
          
    def update(self):
        self.count += 1
        self.label["text"] = str(self.count)     





if __name__ == "__main__":
    gui = tk.Tk()
    app = GUI(master = gui)
    app.mainloop()

When using the schedule module

You can do the same with the "schedule" module. However, this needs to be installed with pip. In addition, it seems that periodical execution in milliseconds cannot be done within the range examined.

If it is in seconds, I think that this is more readable, so it may be better to select it according to the purpose.

pip install schedule
import tkinter as tk
import schedule

class GUI(tk.Frame):
    def __init__(self,master = None):
        super().__init__(master)
        self.master = master
        master.geometry("300x300")
        master.title("Test")
        
        self.count = 0
        
        self.test = tk.Frame(self.master)
        self.test.pack()
        self.label = tk.Label(self.test)
        self.label.pack()
        self.label["text"] = str(self.count)
        
        schedule.every(1).seconds.do(self.update)#Add task to schedule
        self.sc()
        
    def sc(self): #Check the task status regularly with the schedule module
        schedule.run_pending()
        self.after(1, self.sc) #Run recursively
    
    def update(self):
        self.count += 1
        print(self.count)
        self.label["text"] = str(self.count)        

if __name__ == "__main__":
    gui = tk.Tk()
    app = GUI(master = gui)
    app.mainloop()

(Supplement) About thread processing in Python

Python's "threading" module runs only once per instance declaration. This is a specification of the threading module. An example is shown below.

error.py


import threading

th = threading.Thread(target=self.update)
th.start()
th.start() #← Error here "Runtime Error": threads can only be started once」

Recommended Posts

Periodic execution processing when using tkinter [Python3]
Environment variables when using Tkinter
Using Python mode in Processing
Precautions when using pit in Python
Create a python GUI using tkinter
[Python] Be careful when using print
Precautions when using phantomjs from python
When using MeCab with virtualenv python
Precautions when using six with Python 2.5
[VS Code] ~ Tips when using python ~
When using regular expressions in Python
GUI creation in python using tkinter 2
About building GUI using TKinter of Python
GUI creation in python using tkinter part 1
[Python] Speeding up processing using cache tools
Manage multiple execution environments using Python venv
[Python] Matrix multiplication processing time using NumPy
Usual processing notes when using Google Colaboratory
Favicon placement (when using Python, Flask, Heroku)
[python, multiprocessing] Behavior for exceptions when using multiprocessing
[Python] Various data processing using Numpy arrays
Video processing using Python + OpenCV on Mac
Parallel task execution using concurrent.futures in Python
Notify using Notification Center when the execution environment is macOS in Python
Try using Tkinter
VBA user tried using Python / R: Iterative processing
python image processing
How to take multiple arguments when doing parallel processing using multiprocessing in python
Start using Python
Python file processing
Character encoding when using csv module of python 2.7.3
Addition of fixed processing when starting python interpreter
Scraping using Python
What are you using when testing with Python?
[Python] Tkinter template
Points that are easy to make mistakes when using lambda during Python loop processing
Basics of I / O screen using tkinter in python3
Initial settings when using the foursquare API in python
Error due to conflict between python when using gurobi
Check types_map when using mimetypes on AWS Lambda (Python)
Installation method when using RealSense from Python (pyenv edition)
Causes when python version cannot be changed using pyenv
Troublesome story when using Python3 with VScode on ubuntu
How to exit when using Python in Terminal (Mac)
Process csv data with python (count processing using pandas)
Error when executing Python commands without using Anaconda Prompt
Things to keep in mind when processing strings in Python2
Minimum memo when using Python on Mac (pyenv edition)
What I was addicted to when using Python tornado
Things to keep in mind when processing strings in Python3
Minimum notes when using Python on Mac (Homebrew edition)
Python distributed processing Spartan
Operate Redmine using Python Redmine
File processing in Python
Summary when using Fabric
Function execution time (Python)
Python: Natural language processing
Communication processing by Python
Fibonacci sequence using Python
Multithreaded processing in python
Dictionary-type processing using items ()