睡眠而不会中断程序 [英] sleep without interrupting program

查看:83
本文介绍了睡眠而不会中断程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个程序,该程序会在一段时间后进行倒计时,并要求输入秒数以添加到倒计时中. (不是真的,只是一个例子). 有点像这样:

I am creating a program that counts down after a time, and asks for input of seconds to add to the countdown. (Not really, just an example). Kind of like this:

mytime = 10
while True:
   print(time)
   mytime -= 1
   time.sleep(1)
   mytime += int(input('add > '))

有2个问题.

  1. 我希望时间在一秒后仍会下降,但是不想在输入之前等待秒.类似于.我想我需要使用线程.

  1. I want the time to still tick down after a second, but don't want to have to wait the second before inputting. Similar to this. I think I need to use threading.

我也不想等待输入!我只希望它在不等待输入的情况下滴答作响,并在需要时可以输入内容.

I don't want to wait for input either! I just want it to tick down without waiting for input, and when I want I can input things.

感谢您的帮助.

推荐答案

有一种比从0开始创建自己的线程更简单的方法.为您准备了计时器线程:

There is an easier way than making your own thread from 0. Timer thread prepared for you:

import threading

timer = None

def wuf ():
    global timer
    print "Wuf-wuf!"
    timer = threading.Timer(5, wuf)
    timer.start()

timer = threading.Timer(5, wuf)
timer.start()
input() # Don't exit the program

此代码将等待5秒钟,然后开始打印"Wuf-wuf!".每5秒.

This code will wait 5 seconds and then start printing "Wuf-wuf!" every 5 seconds.

如果要从主线程停止它,请执行以下操作:

If you want to stop it from main thread do:

timer.cancel()

但是,如果您使用事件驱动的GUI系统(如wxPython或PyQT)编写GUI应用程序,则应使用它们的事件管理计时器.尤其是如果您要从计时器回调中更改某些GUI状态.

But if you are writing a GUI application using event driven GUI system like wxPython or PyQT, then you should use theirs event managed timers. Especially if you are changing some GUI status from the timer callback.

哦,好的,这是您的完整答案:

Oh, all right, here is your full answer:

import threading

seconds = 1 # Initial time must be the time+1 (now 0+1)
timer = None
def tick ():
    global seconds, timer
    seconds -= 1
    if seconds==0:
        print("%i seconds left" % seconds)
        print("Timer expired!")
        return
    # printing here will mess up your stdout in conjunction with input()
    print("%i second(s) left" % seconds)
    timer = threading.Timer(1, tick)
    timer.start()

seconds += int(input("Initial countdown interval: "))
tick()
while 1:
    seconds += int(input("Add: "))
    if not timer.is_alive():
        print("Restarting the timer!")
        seconds += 1
        tick()

或带有线程的简单版本(但有点笨拙,然后使用threading.Thread):

Or easy version with thread (but a little clumsyer then using threading.Thread):

from thread import start_new_thread as thread
from time import sleep

seconds = 1 # Initial time+1
alive = 0
def _tick ():
    global seconds, alive
    try:
        alive = 1
        while 1:
            seconds -= 1
            if seconds==0:
                print("%i seconds left" % seconds)
                print("Timer expired!")
                alive = 0
                return
            # printing here will mess up your stdout in conjunction with input()
            print("%i second(s) left" % seconds)
            sleep(1)
    except: alive = 0

def tick ():
    thread(_tick,())

# Then same as above:
seconds += int(input("Initial countdown interval: "))
tick()
while 1:
    seconds += int(input("Add: "))
    if not alive:
        print("Restarting the timer!")
        seconds += 1
        tick()

您必须意识到,在线程中使用stdout将在input()输出的提示消息之后插入打印的文本.

You must realize that using the stdout within a thread will insert the printed text after the prompt message outputed by input().

这将令人困惑.如果要避免这种情况,则必须编写另一个线程,该线程将从队列中获取消息并输出.

This will be confusing. If you want to avoid this then you will have to write another thread that will get messages from a queue and output them.

如果最后一条消息是提示消息,则必须将其从屏幕上删除,编写新消息,然后返回提示消息,并相应地定位光标.

If a last message was prompt message, then you will have to remove it from screen, write the new message, then return the prompt message, and position the cursor accordingly.

您可以通过在threading.Thread的子类中实现类似于文件的接口,然后用sys.stdout代替它来实现.也许也可以覆盖input(),以指示何时出现提示信息并读取标准输入.

You could do it by implementing the file-like interface within the subclass of threading.Thread, then substituting sys.stdout with it. Perhaps overriding input() as well to indicate when a prompt message is out and stdin being read.

这篇关于睡眠而不会中断程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆