2013-01-18 11 views
3

我想在Python 3.3中製作一個秒錶,繼續計數,直到你按下按鈕或其他東西,它應該停止計數。這是我的代碼:Python中的秒錶?計數,直到你按空間

seconds = 0 
minutes = 0 
continued = 0 
while continued != 1: 
    print(minutes, ":", seconds) 
    time.sleep(1) 
    if seconds == 59: 
     seconds = 0 
     minutes = minutes + 1 
    else: 
     seconds = seconds + 1 

,而無需使用CTRL + C

我使用沒有GUI或任何東西,使用IDLE在命令提示符下運行只是純粹的Python代碼。

+0

那麼是什麼問題?它會運行,直到你用它殺死它 +

+0

你是否反對使用像'Tkinter'這樣的'gui'? – mgilson

+0

使用沒有GUI或任何東西,純粹使用Python代碼IDLE,在命令提示符下運行 – user1836262

回答

3

試圖等待一個循環中的按鍵,沒有線程或定時器/信號將阻止循環。

在等待按鍵期間讓主循環繼續處理(秒錶)的一種方法是通過線程。一次初步的搜索讓我看到了ActiveState recipe,儘管我找到了this thread的解決方案。

import threading, os, time, itertools, queue 

try : # on windows 
    from msvcrt import getch 
except ImportError : # on unix like systems 
    import sys, tty, termios 
    def getch() : 
     fd = sys.stdin.fileno() 
     old_settings = termios.tcgetattr(fd) 
     try : 
      tty.setraw(fd) 
      ch = sys.stdin.read(1) 
     finally : 
      termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) 
     return ch 

commands = queue.Queue(0) 

def control(commands) : 

    while 1 : 

     command = getch() 
     commands.put(command) # put the command in the queue so the other thread can read it 

     # don't forget to quit here as well, or you will have memory leaks 
     if command == " " : 
      print "Stop watch stopped!" 
      break 

def display(commands): 
    seconds = 0 
    minutes = 0 

    command = "" 

    while 1 : 

     # parsing the command queue 
     try: 
      # false means "do not block the thread if the queue is empty" 
      # a second parameter can set a millisecond time out 
      command = commands.get(False) 
     except queue.Empty, e: 
      command = "" 

     # behave according to the command 
     if command == " " : 
      break 

     print(minutes, ":", seconds, end="") 

     if seconds == 59: 
      seconds = 0 
      minutes = minutes + 1 
     else: 
      seconds = seconds + 1 
     time.sleep(1) 


# start the two threads 
displayer = threading.Thread(None,display,None, (commands,),{}) 

controler = threading.Thread(None, control, None, (commands,), {}) 

if __name__ == "__main__" : 
    displayer.start() 
    controler.start() 
+1

顯然,你不需要線程或信號。 –

+0

編輯以反映線程不是唯一的方法。 – PenguinCoder

0

如果您想爲您的秒錶使用GUI,您可能會對下面的代碼感興趣,它們適用於Python 3.x.

#! /usr/bin/env python3 
import tkinter 
import time 

class StopWatch(tkinter.Frame): 

    @classmethod 
    def main(cls): 
     tkinter.NoDefaultRoot() 
     root = tkinter.Tk() 
     root.title('Stop Watch') 
     root.resizable(True, False) 
     root.grid_columnconfigure(0, weight=1) 
     padding = dict(padx=5, pady=5) 
     widget = StopWatch(root, **padding) 
     widget.grid(sticky=tkinter.NSEW, **padding) 
     root.mainloop() 

    def __init__(self, master=None, cnf={}, **kw): 
     padding = dict(padx=kw.pop('padx', 5), pady=kw.pop('pady', 5)) 
     super().__init__(master, cnf, **kw) 
     self.grid_columnconfigure(1, weight=1) 
     self.grid_rowconfigure(1, weight=1) 
     self.__total = 0 
     self.__label = tkinter.Label(self, text='Total Time:') 
     self.__time = tkinter.StringVar(self, '0.000000') 
     self.__display = tkinter.Label(self, textvariable=self.__time) 
     self.__button = tkinter.Button(self, text='Start', command=self.__click) 
     self.__label.grid(row=0, column=0, sticky=tkinter.E, **padding) 
     self.__display.grid(row=0, column=1, sticky=tkinter.EW, **padding) 
     self.__button.grid(row=1, column=0, columnspan=2, 
          sticky=tkinter.NSEW, **padding) 

    def __click(self): 
     if self.__button['text'] == 'Start': 
      self.__button['text'] = 'Stop' 
      self.__start = time.clock() 
      self.__counter = self.after_idle(self.__update) 
     else: 
      self.__button['text'] = 'Start' 
      self.after_cancel(self.__counter) 

    def __update(self): 
     now = time.clock() 
     diff = now - self.__start 
     self.__start = now 
     self.__total += diff 
     self.__time.set('{:.6f}'.format(self.__total)) 
     self.__counter = self.after_idle(self.__update) 

if __name__ == '__main__': 
    StopWatch.main() 
0

使用詛咒:

import curses 
from datetime import datetime 

SPACE_KEY = ord(' ') 

def run(win): 
    curses.echo() 
    win.timeout(1000) # Wait at most one second for a key. 

    start = datetime.now() 
    while True: 
     now = datetime.now() 
     minutes, seconds = divmod((now - start).total_seconds(), 60) 
     win.addstr(0, 0, "%02d:%02d" % (minutes, round(seconds))) 

     c = win.getch() 
     if c == SPACE_KEY: 
      break 

curses.wrapper(run) 

在Windows環境下,這是一個非的問題,因爲你有kbhitgetch可用msvcrt模塊中。