我目前正在使用python/curses編寫應用程序界面,我想知道是否有可能要求用戶按鍵(cbreak模式)來隱藏或顯示某些面板或窗口而UI則不斷更新。在更新屏幕時Python/curses用戶輸入
我讀了關於curses的官方python文檔並做了一些嘗試,但即使使用cbreak模式和非阻塞輸入模式(nodelay)激活,我也無法使其正常工作(我成功地獲得了用戶輸入,但是以阻止不是我想要的UI爲代價)。
所以我的問題很簡單,可能嗎?如果是,如何?
我可能會誤讀文檔,但我還沒有找到任何其他文檔或示例。
我想過讓應用程序多線程,但我沒有看到這可以幫助我在這種情況下。
感謝您的幫助,建議或指向詳細文檔的指針。
編輯:
我終於結束了下面的多線程代碼,但它並不令人滿意。 U.I是因爲它必須是,但刷新後顯示是borked。
我也不明白爲什麼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()
你可以有一個屏幕線程更新你的屏幕刷新率,並有另一個線程讀取你的用戶輸入,可以改變內部對象(如切換窗口)。 – 2014-10-02 16:07:34
不確定Python的設置是什麼,但詛咒通常在多線程中表現不佳。這樣做的一個正常方法是在超時(或有定時器信號中斷它)調用'select()'時循環,如果輸入已準備好,則調用'getch()';否則更新UI。 – 2014-10-03 03:15:12
我沒有發現任何關於python curses模塊中的「select」方法或函數。 「select」的唯一引用是關於一個名爲「KEY_SELECT」的常量。 與「選擇」關鍵字,我發現這個博客[鏈接](http://cc.byexamples.com/2007/04/08/non-blocking-user-input-in-loop-without-ncurses/)解釋如何用C++解決這個問題。感謝您的幫助。我仍在尋找解決方案。 – Doug713705 2014-10-03 06:05:48