在Python curses UI中调度函数调用

时间:2012-02-14 18:05:49

标签: python curses

我正在尝试编写一个具有curses接口的程序(因此我可以轻松地动态更改设置),并且还能够调用并显示在不同计划上调用的函数的输出。

我无法弄清楚如何在设定的时间段内有效地调用某些内容,并且仍然使用可以随时获取输入的curses循环。

这是一个小程序的例子,试图做我正在说的话。 (不起作用)

import curses, sched, time

from datetime import datetime

def show_time(sc):
    screen.addstr(12, 12, datetime.now())
    sc.enter(1, 1, show_time, (sc,))

screen = curses.initscr()
curses.noecho()
curses.curs_set(0)
screen.keypad(1)

screen.addstr("This is a Sample Curses Script\n\n")

s = sched.scheduler(time.time, time.sleep)
s.enter(1, 1, show_time, (s,))
s.run()
while True:
   event = screen.getch()
   if event == ord("q"): break

curses.endwin()

谢谢!

2 个答案:

答案 0 :(得分:4)

您的脚本似乎有两个问题。

  1. 这一行:

    screen.addstr(12, 12, datetime.now())
    

    将提升TypeError,因为addstr期待str而不是datetime,所以您需要用以下内容替换该行:

    screen.addstr(12, 12, time.strftime("%a, %d %b %Y %H:%M"))
    
  2. 第二个问题是递归调用调用:

    sc.enter(1, 1, show_time, (sc,))
    

    我从未使用过sched模块,但是我稍微扩展了我的知识,似乎.run()将停止,直到所有预定的事件都已完成。

  3. 如果您只对每秒更新屏幕感兴趣,为什么不尝试以下内容:

    import curses
    import time
    import threading
    
    def update_time(screen):
        while 1:
            screen.addstr(12, 12, time.strftime("%a, %d %b %Y %H:%M:%S"))
            screen.refresh()
            time.sleep(1)
    
    screen = curses.initscr()
    curses.noecho()
    curses.curs_set(0)
    screen.keypad(1)
    
    screen.addstr("This is a Sample Curses Script\n\n")
    screen.refresh()
    
    clock = threading.Thread(target=update_time, args=(screen,))
    clock.daemon = True
    clock.start()
    while 1:
        event = screen.getch()
        if event == ord("q"):
            break
    
    curses.endwin()
    

答案 1 :(得分:0)

我认为解决此问题的最佳方法是使用GNU readline作为输入而不是默认的curses输入。然后使用readline的异步功能,以便有一个select循环,您可以从中调用函数。

首先,Python readline库不支持异步readline函数调用,但是it is easy to interface Python directly to readline using ctypes

这样你就有了一个始终处于控制状态的选择循环。如果没有输入,请检查时钟以查看是否该时间运行您的功能。如果没有,请睡几毫秒,检查按键,看时钟再睡一觉。 time.sleep可以处理小数秒。