更新屏幕时,Python / curses用户输入

我目前正在使用python /

curses编写应用程序用户界面,我想知道是否可以要求用户在用户界面不断更新时按下键(cbreak模式)以隐藏或显示某些面板或窗口。

我阅读了有关curses的官方python文档并进行了一些尝试,但是即使使用cbreak模式和非阻塞输入模式(nodelay)已激活,我也无法使其正常工作(我成功获取了用户输入,但是在阻止UI的代价不是我想要的)。

所以我的问题很简单,可能吗?如果是的话,怎么办?

我可能误读了文档,但没有找到任何替代文档或示例。

我曾考虑过使应用程序具有多线程功能,但在这种情况下,我没有看到这对我有什么帮助。

感谢您的帮助,建议或指向详细文档的指针。

编辑:

最后,我得到了以下多线程代码,但并不令人满意。UI已按原样提供,但刷新后显示异常。

我还不明白为什么在隐藏考虑的面板的情况下curses.panel.hidden()返回False。似乎刷新与面板关联的窗口会取消隐藏面板或类似的东西。我真的迷路了!

import threading

import curses, curses.panel

import random

import time

gui = None

class ui:

def __init__(self):

self.feeder = feeder(self)

self.stdscr = curses.initscr()

curses.noecho()

curses.cbreak()

curses.curs_set(0)

self.stdscr.keypad(1)

self.win1 = curses.newwin(10, 50, 0, 0)

self.win1.border(0)

self.pan1 = curses.panel.new_panel(self.win1)

self.win2 = curses.newwin(10, 50, 0, 0)

self.win2.border(0)

self.pan2 = curses.panel.new_panel(self.win2)

self.win3 = curses.newwin(10, 50, 12, 0)

self.win3.border(0)

self.pan3 = curses.panel.new_panel(self.win3)

self.win1.addstr(1, 1, "Window 1")

self.win2.addstr(1, 1, "Window 2")

self.win3.addstr(1, 1, "Press 's' to switch windows or 'q' to quit.")

self.pan1.hide()

self.win1.refresh()

curses.panel.update_panels()

self.win2.refresh()

self.feeder.start()

def ask(self):

while True:

self.win3.addstr(5,1, "Hidden = win1: "+str(self.pan1.hidden())+\

"win2:"+str(self.pan2.hidden()), 0)

self.win3.refresh()

k = self.win3.getkey()

if k == 's':

if self.pan1.hidden():

self.pan2.hide()

self.pan1.show()

self.win1.refresh()

self.win3.addstr(2, 1, "Pan1 restored")

else:

self.pan1.hide()

self.pan2.show()

self.win2.refresh()

self.win3.addstr(2, 1, "Pan2 restored")

self.win3.addstr(5,1, "Hidden = win1: "+\

str(self.pan1.hidden())+\

" win2:"+str(self.pan2.hidden()), 0)

elif k == 'q':

break

self.quit_ui()

def quit_ui(self):

self.feeder.stop()

curses.nocbreak()

self.stdscr.keypad(0)

curses.curs_set(1)

curses.echo()

curses.endwin()

exit(0)

def display_data(self, window, data):

window.addstr(3, 1, data, 0)

class feeder(threading.Thread):

# Fake U.I feeder

def __init__(self, ui):

super(feeder, self).__init__()

self.running = False

self.ui = ui

self.count = 0

def stop(self):

self.running = False

def run(self):

self.running = True

self.feed()

def feed(self):

while self.running:

self.ui.win1.addstr(3, 1, str(self.count)+\

": "+str(int(round(random.random()*9999))))

self.ui.win1.addstr(4, 1, str(self.running))

self.ui.win2.addstr(3, 1, str(self.count)+\

": "+str(int(round(random.random()*9999))))

self.ui.win2.addstr(4, 1, str(self.running))

time.sleep(0.5)

self.count += 1

if __name__ == "__main__":

gui = ui()

gui.ask()

回答:

我终于成功地通过在double while循环中从sys.stdin中读取一个字节,然后避免使用另一个线程来使其工作。以下代码可能无法在MS

Windows上运行,并且由于我不是专业开发人员,因此它可能未经过优化或引发未捕获的错误,但这只是为了使我了解事情的工作原理而准备的草稿(尽管欢迎发表评论)

)。特别感谢Paul Griffiths指导我使用sys.stdin。

#!/usr/bin/python

# -*- coding: iso-8859-1 -*-

import curses, curses.panel

import random

import time

import sys

import select

gui = None

class ui:

def __init__(self):

self.stdscr = curses.initscr()

curses.noecho()

curses.cbreak()

curses.curs_set(0)

self.stdscr.keypad(1)

self.win1 = curses.newwin(10, 50, 0, 0)

self.win1.border(0)

self.pan1 = curses.panel.new_panel(self.win1)

self.win2 = curses.newwin(10, 50, 0, 0)

self.win2.border(0)

self.pan2 = curses.panel.new_panel(self.win2)

self.win3 = curses.newwin(10, 50, 12, 0)

self.win3.border(0)

self.pan3 = curses.panel.new_panel(self.win3)

self.win1.addstr(1, 1, "Window 1")

self.win2.addstr(1, 1, "Window 2")

self.win3.addstr(1, 1, "Press 's' to switch windows or 'q' to quit.")

self.pan1.hide()

def refresh(self):

curses.panel.update_panels()

self.win2.refresh()

self.win1.refresh()

def switch_pan(self):

if self.pan1.hidden():

self.pan2.bottom()

self.pan2.hide()

self.pan1.top()

self.pan1.show()

else:

self.pan1.bottom()

self.pan1.hide()

self.pan2.top()

self.pan2.show()

self.refresh()

def quit_ui(self):

curses.nocbreak()

self.stdscr.keypad(0)

curses.curs_set(1)

curses.echo()

curses.endwin()

print "UI quitted"

exit(0)

class feeder:

# Fake U.I feeder

def __init__(self):

self.running = False

self.ui = ui()

self.count = 0

def stop(self):

self.running = False

def run(self):

self.running = True

self.feed()

def feed(self):

while self.running :

while sys.stdin in select.select([sys.stdin], [], [], 0)[0]:

line = sys.stdin.read(1)

if line.strip() == "q":

self.stop()

self.ui.quit_ui()

break

elif line.strip() == "s":

self.ui.switch_pan()

self.ui.win1.addstr(3, 1, str(self.count)+\

": "+str(int(round(random.random()*999))))

self.ui.win1.addstr(4, 1, str(self.running))

self.ui.win2.addstr(3, 1, str(self.count)+\

": "+str(int(round(random.random()*999))))

self.ui.win2.addstr(4, 1, str(self.running))

self.ui.refresh()

time.sleep(0.1)

self.count += 1

if __name__ == "__main__":

f = feeder()

f.run()

以上是 更新屏幕时,Python / curses用户输入 的全部内容, 来源链接: utcz.com/qa/412270.html

回到顶部