[英]How to delete a subwindow in the python curses module
我有一個使用子窗口的curses應用程序,但我似乎無法刪除它們。
例如,此代碼不起作用:
import curses
def fill(window, ch):
y, x = window.getmaxyx()
s = ch * (x - 1)
for line in range(y):
window.addstr(line, 0, s)
def main(stdscr):
fill(stdscr, 'M')
stdscr.refresh()
stdscr.getch()
subwin = stdscr.subwin(1, 28, 20, 13)
fill(subwin, 'J')
subwin.refresh()
subwin.getch()
del subwin
stdscr.touchwin()
stdscr.refresh()
stdscr.getch()
curses.wrapper(main)
當您運行此代碼時,屏幕將填充“M”,然后當您按下某個鍵時,會創建一個子窗口並填充“J”。 最后,再次按下某個鍵時,代碼會刪除子窗口並完全重繪屏幕。 然而,那些J仍然在那里。
經過一些實驗,我發現調用stdscr的clear()方法會使子窗口運行,但我想恢復背景,而不是刪除它並重寫。 有誰知道可以這樣做的方式?
您使用子窗口有充分的理由嗎? 如果您創建一個新的頂級窗口,那么代碼可以正常工作 - 只需將stdscr.subwin
更改為curses.newwin
,它就可以正常工作。
我不是詛咒專家,但我相信子窗口與其父級共享字符緩沖區,這樣任何一個的更改也會影響另一個。 因此,如果您希望將窗口細分為邏輯區域(可能是菜單欄,主區域和狀態欄),則子窗口非常有用。 但是,如果你正在尋找更像是對話框或彈出菜單的東西,那么你需要的是一個全新的窗口(帶有自己獨立的緩沖區)。
我找不到任何同意或不同意我的ncurses的權威參考,但AIX的手冊頁似乎證實了這一點:
回想一下子窗口共享其父窗口緩沖區。 子窗口覆蓋的區域中的共享窗口緩沖區通過父窗口或其任何子窗口所做的更改會影響共享窗口緩沖區的所有窗口。
當然,這對於ncurses來說並不是決定性的,但是我找不到任何相反的東西,它似乎可以解釋所觀察到的行為。 我還做了一個粗略的實驗,在你的例子中的subwin.getch()
行之后,我添加了這一行:
raise Exception(stdscr.instr(20, 15, 3))
在您的示例中,我將JJJ
作為實際主窗口的內容。 如果我改為使用curses.newwin()
創建窗口而不是stdscr.subwin()
我得到了預期的MMM
。
我不知道有多少特定的Python curses資源,但是關於ncurses的大多數標准教程和文檔對於這種級別非常有用。 當我不得不做一些工作時, 這個文件非常有用。 如果向下滾動到“示例”部分,您將看到菜單彈出窗口不是子窗口 - 他通過以下略微含糊的解釋來暗示:
我們不希望這個新窗口覆蓋前面寫入的字符。 菜單關閉后,他們應該待在那里。 這就是無法將菜單窗口創建為stdscr子窗口的原因。
此外,我記得使用stdscr
和你自己的窗口都可能導致問題 - “官方”ncurses介紹對這類事情有一些警告 。 它還建議完全避免重疊窗口,因為它們顯然容易出錯,但我不記得它們對於短期瞬態模態對話有任何問題(這是我給它們的唯一用途)。 當然,僅僅因為我的簡單用例沒有暴露任何問題並不意味着沒有任何問題。 然而,在像ncurses這樣復雜的事物中,我可以看到保持事物盡可能簡單的智慧。
我希望能有所幫助。 正如我所說,我絕不是一個詛咒專家,但希望這會讓你進一步向前邁進幾步。
這段代碼有兩個問題。
首先,正如前面提到的海報所述,子窗口與父窗口共享一個緩沖區,因此如果你想要一個完全獨立的窗口,你應該使用curses.newwin()
。
其次,使用del
刪除窗口是有問題的,因為它依賴於引用計數/垃圾收集才能正常工作。 (首先,您必須刪除對窗口的所有引用才能使其工作。)我建議使用curses.panel
模塊顯式顯示/隱藏窗口。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.