Vintage appMaker의 Tech Blog

우분투 python에서 ncurses 본문

Source code or Tip/python

우분투 python에서 ncurses

VintageappMaker 2020. 11. 9. 13:47

파이썬 2.7(우분투)에 기본 내장되어있는 ncurses 라이브러리가 그렇게 편하거나 만족스럽지는 않다. 인터넷 검색을 하다보니 한글까지 지원되며 무척 강력하다고 하는 urwid라는 패키지를 찾게 되었다. 우분투에서

다음은 위의 사이트에서 제공되는 예제를 대충 조합하여 만든 process killer 예제이다. urwid가 조금 직관적이지 못하다는 느낌이 들기는 하지만, 그래도 대충 소스를 분석해도 어느 정도 개발이 가능할 듯하다.

# -*- encoding: utf-8 -*-
import urwid
import subprocess
import sys
# process와 pid의 list
plist=[]
def ParseProcInfo(s, sKeyword):
    sline=s.split()
    num = -1
    num = s.find(sKeyword)
    if num == -1: return
    plist.append( (sline[3], int(sline[0])) )
# process 찾기
def SearchFunc(sKeyword):
    rst = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE).communicate()[0]
    proc_list = rst.split('\n')
    for indx in proc_list:
        num = -1
        num = indx.find("PID")
        if num == 2: continue  
        if len(indx) > 0: ParseProcInfo(indx, sKeyword)
    return
# process 죽이기
def DeleteFunc(pid):
    subprocess.Popen(['kill', str(pid)], stdout=subprocess.PIPE).communicate()[0]
class ItemWidget (urwid.WidgetWrap):
    def __init__ (self, id, description, pid):
        self.id  = id
        self.pid = pid
        self.content = '선택 pid[%s]: %s' % (str(pid), description)
        self.item = [
            ('fixed', 15, urwid.Padding(urwid.AttrWrap(
                urwid.Text('%s' % str(id)), 'body', 'focus'))),
            urwid.AttrWrap(urwid.Text('%s' % description), 'body', 'focus'),
        ]
        w = urwid.Columns(self.item)
        self.__super.__init__(w)
    def selectable (self):
        return True
    def keypress(self, size, key):
        return key
def MainWindow(skeyword):
    # 배경색 정의  
    palette = [
        ('body','black', 'dark cyan', 'standout'),
        ('focus','yellow', 'black', 'standout'),
        ('head','yellow', 'black'),
        ('foot','light blue', 'black'),
        ('key','light gray', 'black'),
    ]
    if len(sys.argv) is 1:
        SearchFunc("")
    else:
        SearchFunc(sys.argv[1])
    items = []
    indx=0
    for i in plist:
        items.append( ItemWidget(indx, i[0], i[1]) )
        indx+=1
    
    def keystroke (input):
        if input in ('q', 'Q'):
            focus = listbox.get_focus()[0].pid
            DeleteFunc( focus )
            raise urwid.ExitMainLoop()
        if input is 'enter':
            focus = listbox.get_focus()[0].content
            txtHeader.set_text((str(focus)))
    
    help_msg= [
        ('focus', "사용법"), "    ",
        ('key', "UP"), ", ", ('key', "DOWN"), ", ",
        ('key', "PAGE UP"), " and ", ('key', "PAGE DOWN"),
        " move view  ",
        ('focus', "Q"), " 선택 프로세스 죽이고 종료",
    ]
    
    txtHeader = urwid.Text('')
    header = urwid.AttrMap(txtHeader, 'head')
    footer =  urwid.AttrMap(urwid.Text(help_msg), 'foot')
    listbox = urwid.ListBox(urwid.SimpleListWalker(items))
    view = urwid.Frame(urwid.AttrWrap(listbox, 'body'), header=header, footer=footer)
    loop = urwid.MainLoop(view, palette, unhandled_input=keystroke)
    loop.run()
def main ():
    if len(sys.argv) is 1:
        MainWindow("")
    else:
        MainWindow(sys.argv[1])
    
if __name__ == '__main__':
    main()

사용법)
– 파일명을 kp.py로 한다.
– python kp.py [검색할 프로세스명: 아무것도 없으면 전체 검색]
– 프로세스 리스트 화면 나옴

 

Comments