Python&tkinterで周期処理をしたいんだけどうまく行かなかった話と解決方法

こんにちは

回路の評価用に素人ながらPythonとtkinterを使ってツールを作っています。定期的、周期的にシリアル通信でコマンドを送信したくて色々試していました。調べて簡単に見つかるものはじわじわずれていったり、tkinterで使うと処理が帰ってこなくなったりするケースのものばかりだったのです。

そこでとりあえずうまくいった方法を。

import tkinter as tk
from tkinter import *
import time

root = tk.Tk()
root.geometry("200x50")
root.title("連続動作確認")

cont_bln = tk.BooleanVar()
cont_bln.set(False)

def cont_func():
    global cont_bln
    global cont_start  
    if cont_bln.get() == True:
        now = time.time()
        timediff = int ( ( now - cont_start ) * 1000 ) # msec
        next_count, tmp_time = divmod ( timediff, 1000 )
        next_time = 1000 - tmp_time
        # ここに処理を入れる
        print ( str(next_count) + " " + str(next_time) + " " + str(now) )
        root.after( next_time, cont_func )
        
def cont_pressed():
    global cont_bln
    global cont_start
    if cont_bln.get() == False:
        cont_bln.set(True)
        cont_start = time.time() # UNIX時間(秒)
        print ( "START " + str ( cont_start ) )
        root.after( 1000, cont_func )
    else:
        cont_bln.set(False)


frame = Frame(root, bd=1)
cont_btn = tk.Button(frame, text = "連続/停止", command=cont_pressed)
cont_chk = tk.Checkbutton(frame, variable = cont_bln, text = "連続動作中")

frame.grid(row=0,column=0)
cont_btn.pack(side=LEFT)
cont_chk.pack(side=LEFT)

root.mainloop()

ボタンを押すと1秒ごとに処理が走ります。チェックボックスの状態をそのままフラグとして使っているので、現状では動作中にチェックを外すと止まることになっています。実際使っているものからチャカっと切り出したので変なのが残っている気もしますが。

例えば以下のOK例と比べると、私の環境では少し毎回の精度が悪いようなんですが、なにか乱れる理由あるんですかねぇ。長期的にずれなければ毎回は多少ずれても良かったのでそのまま使っています。ちなみにあまり理解できていないこともありますが、リンク先の方法を使おうとすると処理が帰ってこない状態でした。

qiita.com