ターミナルでpythonでプログレスバーを作ろうと思っています。まず、端末ウィンドウの幅 (列) を取得する必要があります。Python 2.7 では、Windows でこれを実行できる標準ライブラリはありません。Windows コンソール API を手動で呼び出す必要があるかもしれません。
MSDN と Python のドキュメントによると、次のコードを書きました。
import ctypes
import ctypes.wintypes
class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
_fields_ = [
('dwSize', ctypes.wintypes._COORD),
('dwCursorPosition', ctypes.wintypes._COORD),
('wAttributes', ctypes.c_ushort),
('srWindow', ctypes.wintypes._SMALL_RECT),
('dwMaximumWindowSize', ctypes.wintypes._COORD)
]
hstd = ctypes.windll.kernel32.GetStdHandle(ctypes.c_ulong(-11)) # STD_OUTPUT_HANDLE = -11
print hstd
csbi = CONSOLE_SCREEN_BUFFER_INFO()
print ctypes.sizeof(csbi) # <---------------
ret = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(ctypes.c_ulong(hstd), csbi)
print ret
print csbi.dwSize.X
それは正常に動作します。print
コード内のいくつかを削除することにしました。しかし、その後、それはうまくいきません!GetLastError
6 (無効なハンドル) を返します。print 'hello'
何度か試してみると、 、 、import sys
などのコードのポイントされた位置に何かがあるに違いないことがわかりましたsys.stdout.flush()
。最初は、何かをするのに時間がかかるのではないかと思います。それでその位置に入れようとしましtime.sleep(2)
たが、それでもうまくいきません。
でも、struct
代わりに を使えばctypes.Structure
そんな問題はありません。
import ctypes
import struct
hstd = ctypes.windll.kernel32.GetStdHandle(-11) # STD_OUTPUT_HANDLE = -11
csbi = ctypes.create_string_buffer(22)
res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(hstd, csbi)
width, height, curx, cury, wattr, left, top, right, bottom, maxx, maxy = struct.unpack("hhhhHhhhhhh", csbi.raw)
print bufx
無関係なコードがこのような違いを生んだ理由を教えてくれる人はいますか?