Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
70 views
in Technique[技术] by (71.8m points)

python - The root.after() loop cycles twice in one allocated time

I am building a tkinter GUI program which has two loops running together. People have kindly helped me with making "Start" and "Stop" buttons for it (see Creating Tkinter buttons to stop/skip a 2D loop [Solved]). However, a new problem came. In the following code, all the buttons are functioning as we expected. But the speed of the cycling is wrong.

The program is designed to print once per second. However, after finishing printing the first Row, the program starts to print twice per second. I tried a lot but cannot find the reason for that. Can anyone help. Thanks in advance!

import tkinter as tk
root = tk.Tk()

scan_array = [1,"two",3,"ten"]
running = True

Hor_index = 0
Hor_end = 7
Ver_index = 0

def Hor_scan():
    global Hor_index, running, dont_run
    if (Hor_index > Hor_end) and (Ver_index > len(scan_array)):
        running = False
    elif (Hor_index < Hor_end):
        Hor_index += 1
        print ("Row " + str(scan_array[Ver_index-1]) + " Column: " + str(Hor_index))
    else:
        running = False
        Ver_scan()
    if (running):
        root.after (1000, Hor_scan)


def Ver_scan():
    global Ver_index, Hor_index, running
    if Ver_index < len(scan_array):
        Hor_index = 0
        Ver_index += 1
        running = True
        Hor_scan()


def start():
    global Ver_index, Hor_index, running
    Ver_index = 0
    Hor_index = 0
    running = True
    print ("A new run started")
    Ver_scan()

def skip():
    global Ver_index, Hor_index
    Ver_index += 1
    Hor_index = 0

def stop():
    global running
    running = False


btnStart = tk.Button(root,text="Start",command=start)
btnSkip = tk.Button(root,text="Skip",command=skip)
btnStop = tk.Button(root,text="Stop",command=stop)

btnStart.grid()
btnSkip.grid()
btnStop.grid()

root.mainloop()
question from:https://stackoverflow.com/questions/65617700/the-root-after-loop-cycles-twice-in-one-allocated-time

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't see the point of having an extra if (running): statement in Hor_scan, because this

elif (Hor_index < Hor_end):

condition will anyway be only performed if it is "running". You can make the following changes

def Hor_scan():
    global Hor_index, running, dont_run
    if (Hor_index > Hor_end) and (Ver_index > len(scan_array)):
        running = False
    elif (Hor_index < Hor_end):
        Hor_index += 1
        print ("Row " + str(scan_array[Ver_index-1]) + " Column: " + str(Hor_index))
        root.after (1000, Hor_scan)
    else:
        running = False
        Ver_scan()

REASON : If you you call root.after from the condition as you were doing previously, you will end up scheduling one extra call per cycle, because running does not become False right after you are done with the cycle, it initiates another one, only then your program executes else which actually makes running False.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...