如何在编译器休眠时杀死python 3中的time.sleep()

时间:2018-06-17 12:50:44

标签: python tkinter

我想在按下停止按钮后立即退出循环。但是使用这段代码,我只能在执行当前迭代和下一次迭代后才能出现。

这对我的应用来说非常重要,因为iam会将其用于自动化仪器,在按下停止按钮后必须立即停止操作。

# -*- coding: utf-8 -*-
"""
Created on Sun Jun 17 17:01:12 2018

@author: Lachu
"""

import time
from tkinter import *
from tkinter import ttk

root=Tk()

def start():

    global stop_button_state

    for i in range(1,20):
        if (stop_button_state==True):
            break
        else:
            print('Iteration started')
            print('Iteration number: ', i)

            root.update()
            time.sleep(10)
            print('Iteration completed \n')          

def stop_fun():
    global stop_button_state
    stop_button_state=True


start=ttk.Button(root, text="Start", command=start).grid(row=0,column=0,padx=10,pady=10)

p=ttk.Button(root, text="Stop", command=stop_fun).grid(row=1,column=0)

stop_button_state=False

root.mainloop()

3 个答案:

答案 0 :(得分:2)

time.sleep与GUI程序一起使用通常不是一个好主意,因为它会将所有置于睡眠状态,因此GUI无法自行更新或响应参加活动。此外,当您想要中断sleep时,它会变得混乱。

我已调整您的代码以使用threading模块中的Timer。我们可以立即轻松中断此Timer,并且它不会阻止GUI。

为了完成这项工作,我将您的计数for循环移动到了生成器中。

如果在计数过程中按下“开始”按钮,它将告诉您它已在计数中。当计数周期结束时,无论是通过按停止,还是通过到达数字的末尾,您可以再次按开始以开始新的计数。

import tkinter as tk
from tkinter import ttk
from threading import Timer

root = tk.Tk()

delay = 2.0    
my_timer = None

# Count up to `hi`, one number at a time
def counter_gen(hi):
    for i in range(1, hi):
        print('Iteration started')
        print('Iteration number: ', i)
        yield
        print('Iteration completed\n')

# Sleep loop using a threading Timer
# The next `counter` step is performed, then we sleep for `delay`
# When we wake up, we call `sleeper` to repeat the cycle
def sleeper(counter):
    global my_timer
    try:
        next(counter)
    except StopIteration:
        print('Finished\n')
        my_timer = None
        return
    my_timer = Timer(delay, sleeper, (counter,))
    my_timer.start()

def start_fun():
    if my_timer is None:
        counter = counter_gen(10)
        sleeper(counter)
    else:
        print('Already counting')

def stop_fun():
    global my_timer
    if my_timer is not None:
        my_timer.cancel()
        print('Stopped\n')
        my_timer = None

ttk.Button(root, text="Start", command=start_fun).grid(row=0, column=0, padx=10, pady=10)
ttk.Button(root, text="Stop", command=stop_fun).grid(row=1,column=0)

root.mainloop()

答案 1 :(得分:1)

使用print()比使用线程更好:

在任何事件中,正如其他人指出的那样,在GUI中使用root.after是一个坏主意。

您也不应该将您的按钮命名为与您的功能相同。

调用time.sleep,这里也没有必要。

root.update

答案 2 :(得分:-1)

如果不使用单独的线程,您可以始终遍历sleep命令,这将使代码更具响应性 例如这将减少您在单击停止和循环退出到1/10秒之间的等待,同时在循环之间保持10秒的间隙。

# -*- coding: utf-8 -*-
"""
Created on Sun Jun 17 17:01:12 2018

@author: Lachu
"""

import time
from tkinter import *
from tkinter import ttk

root=Tk()
stop_button_state=False

def start():

    global stop_button_state
    for i in range(1,20):
        if (stop_button_state==True):
           break
        print('Iteration started')
        print('Iteration number: ', i)
        for i in range(100):
            root.update()
            time.sleep(0.1)
            if (stop_button_state==True):
                break
        print('Iteration completed \n')

def stop_fun():
    global stop_button_state
    stop_button_state=True

ttk.Button(root, text="Start", command=start).grid(row=0,column=0,padx=10,pady=10)
ttk.Button(root, text="Stop", command=stop_fun).grid(row=1,column=0)
root.mainloop()