기획자 본인만큼 잡다한 블로그

greentec.egloos.com

포토로그


통계 위젯 (블랙)

1726
184
83810

flag counter

Flag Counter


Python 3.x curses 라이브러리에서 한글 출력 - Windows 10 프로그래밍

배경 설명


이직 후 여러 가지 작업을 하고 있는데 그 중 서브 작업으로 간단하게 파이썬 툴을 만들던 중,
윈도우 환경 터미널에서 키 입력을 바로 받고 싶은 간단한 문제에 봉착했다.
curses 라는 라이브러리를 깔았지만 한글 출력이 잘 보이지 않았다.
인터넷에는 관련된 레퍼런스가 없어서 못 찾다가, 반나절 동안 삽질 후 해결책을 여기에 공유한다.


핵심 요약


addstr() 대신 addch() 를 사용해서 한 글자씩 출력하자.
[optional] 터미널 글씨체를 래스터 글꼴로 바꾸자(굴림체 등의 경우 글의 끝부분이 잘릴 수도 있음).


상세


어떤 숫자를 입력받을 때 보통 알고리즘 문제 같은 곳에서는 이렇게 입력을 받는다.
n=int(input())




그런데 이런 경우에는 숫자를 입력한 후 엔터를 쳐줘야 문장의 다음 부분으로 넘어가게 된다. 하지만 숫자 키 하나만 눌렀을 때 바로 다음으로 넘어갈 수는 없는 걸까? 찾다 보니 curses 라는 라이브러리가 있었다. pip install curses 라고 입력하면 windows 에서는 설치되지 않고, 링크의 curses‑2.2‑cp36‑cp36m‑win_amd64.whl 파일을 다운받아서 해당 경로에서 직접 설치했다. 자신의 시스템에 설치된 python 버전에 따라 알맞은 파일을 설치하면 된다.
pip install curses‑2.2‑cp36‑cp36m‑win_amd64.whl




이제 getch() 함수를 이용해서 키 입력을 바로 받을 수 있다. 간단한 예제 프로그램을 만들어서 테스트를 해보면,
import curses

def main(screen):
screen.clear()
screen.addstr(0, 0, 'Hello World')

while True:
c = screen.getch()
screen.addstr(1, 0, str(c))

if c == 3: # Ctrl+C
break


curses.wrapper(main)




터미널에서 다음 스크립트를 실행하면 이런 화면이 표시된다.
현재 키 입력을 y=1, x=0 위치에 출력한다. 키 값은 int 이고 출력할 때는 str 이어야 하기 때문에 형 변환을 해줬다.
Ctrl + C 의 키 값은 3인데, 누르면 프로그램을 빠져나가게 된다. 달리 프로그램을 빠져나가는 방법은 찾아본 바로는 없었다. 터미널 창을 끄거나 해야한다.



그럼 한글을 출력해보자.
인터넷에서 유니코드 출력을 위해서는 locale 을 바꿔줘야 한다고 해서 그 부분을 추가하고, 한글 텍스트를 넣어보았다.
import curses
import locale
locale.setlocale(locale.LC_ALL, '')

def main(screen):
screen.clear()
screen.addstr(0, 0, '터미널에서 다음 스크립트를 실행하면 이런 화면이 표시된다.')

while True:
c = screen.getch()
screen.addstr(1, 0, str(c))

if c == 3: # Ctrl+C
break


curses.wrapper(main)




결과는 아래와 같다. 한글이 깨져서 나온다.



문제를 해결하기 위해 여러 가지 시도를 해봤는데 해답은 의외로 간단한 곳에 있었다. addstr() 함수 대신에 addch() 함수, 즉 한 글자씩 떼어서 출력하면 잘 나왔다. 알고나니 허무한 해결책이었다.
참고로 글씨 중간에 커서가 있으면 글씨가 밀리는 문제가 있어서 한글 출력 후 커서 위치를 바꿔주기 위해 빈 칸을 출력했다.
import curses
import locale
locale.setlocale(locale.LC_ALL, '')

def main(screen):
screen.clear()
s = '터미널에서 다음 스크립트를 실행하면 이런 화면이 표시된다.'
for idx, char in enumerate(s):
screen.addch(0, idx, char)
screen.addstr(1, 0, ' ')

while True:
c = screen.getch()
screen.addstr(1, 0, str(c))

if c == 3: # Ctrl+C
break


curses.wrapper(main)




이제 한글이 정상적으로 출력된다.




알고나니 무척 간단한 방법이었다. 그리고 내 경우에는 파일에서 한글을 읽어들일 때 글씨의 중간이 잘리는 문제가 있어서 터미널의 기본 글꼴을 바꿔서 문제를 해결했다. 같은 현상을 겪는 경우 참고가 될 수 있을 것 같다.



핑백

덧글

댓글 입력 영역

애드센스