cursesにて端末のリサイズができない。
情報源
- python3-curses-doesnt-recognize-curses-resizeterm
- python-curses-handling-window-terminal-resize
- cursesでKEY_RESIZEがとれているかだけを見るプログラム
- where-does-curses-inject-key-resize-on-endwin-and-refresh
API
やってみた
できなかった。
- 以下のコードを動作させる
- 端末の端をマウスでドラッグしてウインドウのサイズを変更する
- クラッシュした
- エラーも何も出さず、突然、端末がコードを実行する前の状態にもどった
#!/usr/bin/env python3 # coding: utf8 import curses def main(stdscr): if stdscr.getch() == curses.KEY_RESIZE: curses.resizeterm(*stdscr.getmaxyx()) stdscr.clear() stdscr.refresh() curses.wrapper(main)
以下のコードは動いた。クラッシュもしない。でもこれ、resizeterm関数を呼んでない。しかもgetchとはべつのイベント取得を実装せねばならないっぽい。initscr
を2箇所で呼んでいるなどおかしな実装をせざるを得ない。
from curses import initscr, endwin from signal import signal, SIGWINCH from time import sleep stdscr = initscr() def redraw_stdscreen(): rows, cols = stdscr.getmaxyx() stdscr.clear() stdscr.border() stdscr.hline(2, 1, '_', cols-2) stdscr.refresh() def resize_handler(signum, frame): endwin() # This could lead to crashes according to below comment stdscr.refresh() redraw_stdscreen() signal(SIGWINCH, resize_handler) initscr() try: redraw_stdscreen() while 1: # print stuff with curses sleep(1) except (KeyboardInterrupt, SystemExit): pass except Exception as e: pass endwin()
さすがにこんなコードは書きたくない。
結論
端末のリサイズはあきらめる。
いきなりクラッシュされるのはつらいが、実装をクソコードにしてしまうよりはマシだと思うことにする。cursesまたはpythonが悪いに違いない。私は悪くない。
対象環境
- Raspbierry pi 4 Model B
- Raspberry Pi OS buster 10.0 2020-08-20 ※
- bash 5.0.3(1)-release
$ uname -a Linux raspberrypi 5.4.83-v7l+ #1379 SMP Mon Dec 14 13:11:54 GMT 2020 armv7l GNU/Linux