2017-07-25 29 views
0

Was ist der richtige Weg, um eine Zeile an den unteren Rand eines Terminal-Fensters zu drucken, das die Größenänderung verarbeiten kann?Python Curses Terminal Größe ändern Problem

import curses 
from curses import wrapper 

def main(stdscr): 
    inp = 0 
    y,x = stdscr.getmaxyx() 
    stdscr.clear() 
    stdscr.nodelay(1) 
    while inp != 48 and inp != 27: 
     stdscr.addnstr(y-1,0, 'I AM KILL TERMINAL WHEN RESIZE AAAAAAAH', x) 
     inp = stdscr.getch() 

wrapper(main) 

Sobald ich das Terminal zu weniger Spalten dann die Länge der Zeichenfolge der Größe versucht, es auf die nächste Zeile und Fehler zu wickeln aus. Ich kann nichts in der Dokumentation zum Deaktivieren des Wrappings sehen.

Ich habe versucht, meine max y, x Werte vor der addstr Funktion zu aktualisieren.

while inp != 48 and inp != 27: 

     if (y,x) != stdscr.getmaxyx(): 
      y,x = stdscr.getmaxyx() 

     stdscr.addnstr(y-1,0, 'I AM KILL TERMINAL WHEN RESIZE AAAAAAAH', x) 
     inp = stdscr.getch() 

ich auch habe versucht SIGWINCH Erfassung

while inp != 48 and inp != 27: 

     def resize_handler(signum, frame): 
      stdscr.erase() 
      stdscr.refresh() 
      termsize = shutil.get_terminal_size() 
      curses.resizeterm(termsize[1],termsize[0]) 
      y,x = stdscr.getmaxyx() 

     signal.signal(signal.SIGWINCH, resize_handler) 

     stdscr.addnstr(y-1,0, 'I AM KILL TERMINAL WHEN RESIZE AAAAAAAH', x) 
     inp = stdscr.getch() 

Doch diese beiden scheinen früh genug, um das Terminal-Update zu erfassen.

+0

diesen Link https Siehe: // mail .python.org/pipermail/python-list/2007-Februar/426098.html – Bijoy

Antwort

1

Der richtige Weg SIGWINCH für das gegebene Beispiel zu handhaben ist, die stdscr.addnstr und stdscr.getch Anrufe in einem Block von Code zu wickeln, die den Text (Begrenzung der Anzahl der Zeichen an die bestehenden Terminalgröße) neu gezeichnet, dies zu tun so oft wie das Terminal in der Größe geändert wird.

Das Problem ist, dass der Anruf stdscr.getch (tatsächlich ist die C-Funktion in Ncurses die Arbeit) unterbrochen ist. Das macht die refresh, die in der Schleife im ersten Beispiel durchgeführt wird. ncurses 'stdscr.getch sollte eine KEY_RESIZE von stdscr.getch Aufruf, die Anwendungen verwenden können, um zu sagen, wann Dinge neu zu streichen. (Dies funktioniert mit Ausnahme von OpenBSD, die die Funktion aus nicht technischen Gründen auslässt).

Durch das Einrichten einer Signalkennung kann ncurses der Anwendung nicht mitteilen, dass die Größe des Terminals geändert wurde. Beim Lesen des zweiten Beispiels scheint die ncurses-Bibliothek immer noch auf die Eingabe zu warten, nachdem die Aktualisierung durchgeführt wurde, die den Text addnstr auf den Bildschirm bringt (vor der ersten Größenänderung).

Die Diskussion Curses and resizing windows zeigt eine Fallgrube: wenn die Anwendung gehen Zeichen nicht zu lesen, es wird nie KEY_RESIZE sehen. Aber dein Beispiel macht das nicht. Ich würde die Signal-Handler verwerfen (außer in der Quere, es Signal unsichere Funktionen verwendet, den Python brechen kann), und ändern Sie das erste Beispiel so etwas wie diese:

import curses 
from curses import wrapper 

def main(stdscr): 
    inp = 0 
    y,x = stdscr.getmaxyx() 
    stdscr.clear() 
    stdscr.nodelay(1) 
    while inp != 48 and inp != 27: 
     while True: 
      try: 
       stdscr.addnstr(y-1,0, 'I AM KILL TERMINAL WHEN RESIZE AAAAAAAH', x) 
      except curses.error: 
       pass 
      inp = stdscr.getch() 
      if inp != curses.KEY_RESIZE: 
       break 
      stdscr.erase() 
      y,x = stdscr.getmaxyx() 

wrapper(main) 
+0

Brilliant, danke – huwwp