Contents
Pythonバッチにお飾り curses メニュー
前置き
Pythonバッチにお飾りGUIに引き続き「UIをさぼる」ネタ。
サボるのが目的であるから、あくまで不真面目に取り組む。
curses でやりたくなること、案外多い。いわゆる「サーバ機」のリモート保守、みたいなことを考える。この場合、保守プログラムを構築するには VPN でもあてに出来ない限りは自ずと選択肢が限られて、WEB ベースのものを作りこむか、telnet (ssh) クライアント経由で CUI か。
お飾りメニュー駆動バッチの仕様
- 10個のメニューアイテムから選べるだけでいい
- 日本語はいらない
- メニューからユーザが選択したら画面クリアして目的のことをする
- 目的のことの出力が終わったらキー入力待ちする
- キー入力があったらメニューに戻る
Pythonバッチにお飾りGUI同様、仕様というよりは願望。これだけで出来てしまうことは限られるが、「これでいいならそれでいい」。
ファイルのダイジェストを取るだけの
ただの例です。本気でこの目的でこんなことするヤツはいない。
1 import sys
2 import curses
3
4 def _menu(screen, menu_title, items):
5 # 日本語は出来ないことはないようだが、頑張りすぎると不毛なので割り切ったほうがいい。
6 # Windowsのことまで考えると border などの装飾はやめたほうがいい。ガッカリするはず。
7 curses.init_pair(1, curses.COLOR_BLUE, curses.COLOR_WHITE)
8 screen.keypad(1)
9 pos = 0
10 x = None
11 hn = {
12 True: curses.color_pair(1) | curses.A_BOLD,
13 False: curses.A_NORMAL
14 }
15 while x != ord('\n'):
16 screen.clear()
17 screen.addstr(2, 2, menu_title, curses.A_STANDOUT)
18 for i, item in enumerate(items):
19 screen.addstr(4 + i, 4,
20 "{} - {}".format(i, item),
21 hn[pos == i])
22 x = screen.getch()
23 if x in [ord(str(i)) for i in range(len(items))]:
24 pos = x - ord('0')
25 # http://blog.skeltonnetworks.com/tag/python-curses/ で
26 # curses.KEY_* が効かない、と困っていたが、ワタシの環境では
27 # 使えた。なんだろうね?
28 elif x == curses.KEY_DOWN: #258:
29 pos = (pos + 1) % len(items)
30 elif x == curses.KEY_UP: #259:
31 pos = (len(items) + pos - 1) % len(items)
32 elif x != ord('\n'):
33 curses.flash()
34 return items[pos]
35
36 def main(screen, fn):
37 import hashlib
38 filecontents = open(fn, "rb").read()
39
40 curses.start_color()
41 title = "hashlib"
42 menuitems = [
43 'md5',
44 'sha1',
45 'sha224',
46 'sha256',
47 'sha384',
48 'sha512',
49 'Exit',
50 ]
51 while True:
52 selection = _menu(screen, title, menuitems)
53 if selection == "Exit":
54 break
55 if sys.platform == "win32":
56 import os
57 os.system("cls")
58 else:
59 sys.stdout.write("\x1b[2J\x1b[H")
60 digester = hashlib.new(selection)
61 digester.update(filecontents)
62 print(digester.hexdigest())
63 screen.getch()
64
65 if __name__ == '__main__':
66 import locale
67 locale.setlocale(locale.LC_ALL, '')
68 curses.wrapper(main, sys.argv[1])
参考にしたサイト
随分前に、本当にこれに近いことを仕事でやったことはあったが、それ以来やっていなかったので、あちこち参考にした。
基本コードベースは Python Curses – Custom Menu|Programming ThoughtsとCode Project: Build an Ncurses UI with Python。
画面クリアはなんだか皆苦労しているようで、clear terminal in python|stackoverflowより。
Snake ゲームはまぁお約束ですな。
本気の curses の入り口としては
[python]プロトタイプをcursesで|DoRuby!が良いかも。チャットプログラムを作ってる。
ネタとして面白いのは Python Curses Example of Dungeon-Building Algorithm。
NetHack作れるぞ。
curses Windows版
Windows版にも curses モジュールそのものは存在している。ただ、curses 本体は、自分でインストールしないと使えない。
setuptoolsはインストール済み、として、
1 me@host: ~$ easy_install pip
2 me@host: ~$ pip install wheel
http://www.lfd.uci.edu/~gohlke/pythonlibs/#curses より curses-2.2-cp27-none-win_amd64.whl (等貴方の環境に合ったもの)を入手、
1 me@host: ~$ pip install curses-2.2-cp27-none-win_amd64.whl
これで Python の curses が使えるようになる。
2021-03-29追記
まず、Windows 版 curses については、最近は(?)「windows-curses」パッケージがある:
1 me@host: ~$ py -3 -m pip install windows-curses
最初に書いたときからあったのかもしれないけど、少なくとも今はこれで入手出来るので、こちらをどぞ。
あと、ちょっと個人的に「シンプルなデジタル時計」がご入用だったので、ちょいとご気楽に作ってみたのがあるので、ご賞味どぞー(要: pillow):
「curses 事始め」にはちょうどいい気がしたの。
2021-04-03更に追記
一つ上のサンプルと大差はないんだけれど、こういうのをやりたい、て人は割といる気がするんで一応(要psutil):
「Unix の df の(簡易)ビジュアライズ」ね。