在Python用户界面中调度函数调用

在Python用户界面中调度函数调用,python,curses,Python,Curses,我正在尝试编写一个程序,该程序将有一个curses接口,这样我就可以轻松地动态更改设置,还可以调用和显示在不同计划中调用的函数的输出 我不知道如何在设定的时间段内高效地调用某些东西,并且仍然使用可以随时接收输入的curses循环 下面是一个小程序的例子,它试图实现我所说的。不起作用 import curses, sched, time from datetime import datetime def show_time(sc): screen.addstr(12, 12, date

我正在尝试编写一个程序,该程序将有一个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()

谢谢

您的脚本似乎有两个问题

这一行:

screen.addstr(12, 12, datetime.now())
将引发TypeError,因为addstr预期的是str而不是datetime,所以需要将该行替换为以下内容:

screen.addstr(12, 12, time.strftime("%a, %d %b %Y %H:%M"))
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()
第二个问题是递归sched调用:

sc.enter(1, 1, show_time, (sc,))
我从未使用过sched模块,但我扩展了我的知识,似乎在所有计划的事件完成之前,.run将停止

如果您只想每秒钟更新一次屏幕,为什么不尝试以下方法:

screen.addstr(12, 12, time.strftime("%a, %d %b %Y %H:%M"))
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()

您的脚本似乎有两个问题

这一行:

screen.addstr(12, 12, datetime.now())
将引发TypeError,因为addstr预期的是str而不是datetime,所以需要将该行替换为以下内容:

screen.addstr(12, 12, time.strftime("%a, %d %b %Y %H:%M"))
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()
第二个问题是递归sched调用:

sc.enter(1, 1, show_time, (sc,))
我从未使用过sched模块,但我扩展了我的知识,似乎在所有计划的事件完成之前,.run将停止

如果您只想每秒钟更新一次屏幕,为什么不尝试以下方法:

screen.addstr(12, 12, time.strftime("%a, %d %b %Y %H:%M"))
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()

我认为解决这个问题的最好方法是对输入使用GNU readline,而不是默认的curses输入。然后使用readline的异步功能,这样就有了一个select循环,可以从中调用函数

但是,首先,Python readline库不支持异步readline函数调用


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

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

但是,首先,Python readline库不支持异步readline函数调用


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

递归调用是我见过的唯一能够为事件重复sched调用的方法。我担心如果我将它放入while-True循环,它会打乱日程安排。@user1209675:如果您只对更新屏幕感兴趣,而不关心它是否与sched模块一起使用,为什么不尝试使用线程呢?我用一个例子更新了我的答案。递归调用是我见过的唯一能够为事件重复sched调用的方法。我担心如果我将它放入while-True循环,它会打乱日程安排。@user1209675:如果您只对更新屏幕感兴趣,而不关心它是否与sched模块一起使用,为什么不尝试使用线程呢?我用一个例子更新了我的答案。