Python을 이용하여 현재 실행 중인 프로세스 리스트 정보를 따오는 걸 오랜만에 할 생각에 검색 좀 하다가


예전에는 Win32com을 이용했던 거 같은데 그 것 보다 아주 심플한 녀석을 발견..


언제 wmi를 직접 사용할 수 있는 모듈이 나온 건지...


분명 나중에 또 까먹을테니 메모 메모~


import wmi

WMI_OBJ = wmi.WMI()

process_list = WMI_OBJ.Win32_Process()

for process in process_list:
    print process
    break


이전에는 분명 win32com의 모듈을 시작으로 코드가 길었었는데.. wmi를 직접 사용하는 모듈이 나올 줄이야...


프로세스의 전체 리스트를 출력하면 양이 많아지니 딱 처음 프로세스의 정보만 출력하고 break 를 걸어보면


System Idle Process 의 정보가 확인된다.


반환 된 값은 아래와 같은 인스턴스 형태로 모든 프로세스의 정보를 제공한다. 원하는 정보를 골라서 써먹으면 되겠음.





instance of Win32_Process

{

        Caption = "System Idle Process";

        CreationClassName = "Win32_Process";       

        CreationDate = "20200423084455.052129+540";

        CSCreationClassName = "Win32_ComputerSystem";

        CSName = "SLAYS_DESKTOP";

        Description = "System Idle Process";

        Handle = "0";

        HandleCount = 0;

        KernelModeTime = "655224687500";

        Name = "System Idle Process";

        OSCreationClassName = "Win32_OperatingSystem";

        OSName = "Microsoft Windows 10 Pro|C:\\Windows|\\Device\\Harddisk2\\Partition1";

        OtherOperationCount = "0";

        OtherTransferCount = "0";

        PageFaults = 9;

        PageFileUsage = 60;

        ParentProcessId = 0;

        PeakPageFileUsage = 60;

        PeakVirtualSize = "8192";

        PeakWorkingSetSize = 12;

        Priority = 0;

        PrivatePageCount = "61440";

        ProcessId = 0;

        QuotaNonPagedPoolUsage = 1;

        QuotaPagedPoolUsage = 0;

        QuotaPeakNonPagedPoolUsage = 1;

        QuotaPeakPagedPoolUsage = 0;

        ReadOperationCount = "0";

        ReadTransferCount = "0";

        SessionId = 0;

        ThreadCount = 12;

        UserModeTime = "0";

        VirtualSize = "8192";

        WindowsVersion = "10.0.18363";

        WorkingSetSize = "8192";

        WriteOperationCount = "0";

        WriteTransferCount = "0";

};

블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

Pyinstaller는 파이썬을 exe로 빌드해주는 플러그인이다.

(py2exe가 지원하지 못하는 몇 부분 때문에 같이 사용하고 있음..)


개인 랩탑에서는 문제 없이 사용하고 있던 플러그인이 회사 랩탑에서는 파일 빌드 시에


unicodedecodeerror: 'ascii' codec can't decode byte 0xc5 in position~~ (이하 생략)


메세지가 발생하는 것이었던 것이었...




음! 유니코드를 쓰지도 쓸 일 조차 없던 코드를 빌드하는데 계속 unicodedecodeerror 오류가


발생을 하고 에러 발생 지점은 내가 작성한 코드가 아닌 pyinstaller 안에서 터지고 있던 것.


뭐가 문제인지 삽질을 하면서 찾으려다가(일일히 코드 따라가서면서 디버깅 하기엔 노가다가 너무 심하므로....)


아무리 봐도 개인 랩탑과 같은 세팅을 했는데도 에러가 왜 터질가 고민 끝에 아주 심플하게도


유니코드가 원인이라면~~~ 음~~ 하면서 두 랩탑의 차이를 고민해보니


"윈도우 계정 폴더" 딱 하나만 차이가 났었다.


개인 랩탑은 계정명이 영문... 회사 것은 계정명이 한글~~


계정명을 영문으로 변경하니 아주 잘 되는 것.....


pyinstaller를 분명 계정 폴더 내부가 아닌 곳에 설치했는데도 계정명의 영향을 받다니.. 좀 아이러니 하지만


어쨌든 계정 폴더명을 영문으로 변경하니 해결되었던 것.......




그냥~ 까먹을까봐 오랜만에 여기에 기록을 해둔다.







블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요


[그림. 1] Drives



기존에 작성했던 루트에서 작성하면 문제될 것이 없었는데, 함수화 시켜버리면 ValueError 를 뿜어내서 다시 정리를 해본다.



로컬 드라이브 또는 이동식 저장장치 중, 인식되어 있는 녀석들의 드라이브 명을 알아내는 소스를 검색하다가

알게 된 것...


이거 땜에 무슨 HID Device를 쪼물딱 거릴 때 쓰는 패키지도 깔고 그랬지만 그냥 이게 젤 편한 것 같다.


그러나... 멀티리더기를 처리할 수 없는 장벽을 만나서 아직은 더 검색해야 한다. ㅠㅠ


멀티 리더기는 usb가 안 꼽혀 있어도 드라이브가 활성화 되어 있기에 그걸 건드리면 윈도우가 애러를 내뱉는다.


usb가 꼽혔는지 안 꼽혔는지 확실히 체크하려면 드라이브에 접근하는 어떠한 함수라도 써야 하는데, 그 짓을 했다가


애러가 터지는 것...


일반 USB 드라이브는 장치를 연결할 때에 디바이스가 활성화 되는 반면 멀티리더기는 그냥 계속 활성화 상태라서


좀 짜증이 난다.



밑의 코드가 바로 함수화를 안 하면 잘 되는데, 함수화 시키면 애러를 뿜었던 코드이다.


# -*- coding: utf-8 -*-

import win32api
import win32file
import os

#
# cut-and-pasted from MSDN
#
DRIVE_TYPES = """
0 Unknown
1 No Root Directory
2 Removable Disk
3 Local Disk
4 Network Drive
5 Compact Disc
6 RAM Disk
"""
drive_types = dict((int (i), j) for (i, j) in (l.split ("\t") for l in DRIVE_TYPES.splitlines () if l))

drives = (drive for drive in win32api.GetLogicalDriveStrings ().split ("\000") if drive)
# for drive in drives:
# type = drive_types[win32file.GetDriveType (drive)]
# if type == 'Removable Disk':
# print drive

drive_list = []

for drive in drives:
type = drive_types[win32file.GetDriveType (drive)]
if type == 'Removable Disk':
try:
drive_list.append(type)
except WindowsError, e:
pass


이 것을 함수(메소드)로 사용해도 애러가 나지 않도록 검색하고 알아내서 정리한 코드는 이것이다.

그리고 코드 자체를 다 뜯어 고치니깐 위에 언급했떤 멀티리더기의 빈 드라이브가 인식된 상태에서도 에러가 나지 않는다. ㅋ


def get_drive(self):
"""DRIVE_TYPES
0 Unknown // win32file.DRIVE_UNKNOWN
1 No Root Directory // win32file.DRIVE_NO_ROOT_DIR
2 Removable Disk // win32file.DRIVE_REMOVABLE
3 Local Disk // win32file.DRIVE_FIXED
4 Network Drive // win32file.DRIVE_REMOTE
5 Compact Disc // win32file.DRIVE_CDROM
6 RAM Disk // win32file.DRIVE_RAMDISK
"""
drive = GetLogicalDriveStrings()
drive = drive.split('\000')[:-1]
drive_list = []
rdrive = []

for drv in drive:
if win32file.GetDriveType(drv) == win32file.DRIVE_REMOVABLE:
drive_list.append(drv)
for drv in drive_list:
try:
if os.path.getsize(drv) >= 0:
rdrive.append(drv)
except OSError:
pass
return rdrive


os.path.getsize() 메소드를 쓰는 이유는 멀티리더기의 빈 드라이브를 걸러내기 위함이다.


빈 드라이브를 검색 시 익셉션이 발생하기 때문에 except로 pass를 시켜 재껴버린다.

(분명 첫 번째 코드에서는 except pass를 해도 에러가 터졌는데 코드를 싹 다 바꾸니 잘 된다. -_-)


결국 win32api와 win32file 패키지를 이용하는 것이고 드라이브의 속성(이름)에 따라서 내가 원하는 속성을 갖는 드라이브를 가져다가 쓰면 되겠다.


주석 처리 해놓은 부분은 드라이브 타입에 따른 번호와 뜻을 열거한 거고, 각 번호 별로 win32file에 정의된 맴버와 어떻게 매칭되는지를 보여주는 것이다.


로지컬 드라이브 스트링을 모두 긁어온 뒤에 각 드라이브 별로 로컬인지, 이동식 디스크 인지, 시디롬인지를 for if 문을 통해 걸러내주면 되는 것이다.


두 번째 코드에서는 DRIVE_REMOVABLE, 즉 이동식 디스크만을 리스트로 따로 묶어주고 있는 것이다.

블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

파이썬에서 외부 파일을 실행하기 위해서 많이들 사용하는 명령어는 다음의 것들일 것이다.


 - os.system("실행할 파일")

 - os.popen("실행할 파일")

 - subprocess.call("실행할 파일")


이 3가지 중 os 모듈을 이용하는 것은 실행한 파일이 종료되기 전까지는 계속 메모리에 상주가 된다.

os.system과 os.popen은 cmd에서 명령어를 입력하는 것과 같은 동작을 해준다.

즉, "실행할 파일"을 구동시키게 되면 실행된 것들의 프로세싱이 끝나기 전 까지는 프로세스로서 cmd.exe가

메모리에 상주되는 것이다.


subprocess만이 cmd를 통하지 않고 바로 실행을 시켜주지만 여전히 "실행할 파일"은 본인을 실행시킨 프로세스에

자식 프로세스로 귀속이 된다.

(cmd를 거치지는 않았지만 python.exe에 귀속되어진다.)






[그림. 1] 3가지 메소드의 프로그램 실행




[그림. 1]은 위의 3가지 메소드를 이용하여 "계산기", "메모장", "그림판"을 실행한 결과이다.

(os 모듈은 cmd를 모두 이용하므로 스레드를 할당해서 실행해야 두 개가 동시 실행된다.)


import os, subprocess, thread

calc = ("c:\windows\system32\\calc.exe")
notepad = ("c:\windows\system32\\notepad.exe")
paint = ("c:\windows\system32\\mspaint.exe")

def os_system(path):
os.system(path)


def os_popen(path):
os.popen(path)


thread.start_new_thread(os_system, (calc,))
thread.start_new_thread(os_popen, (notepad,))


subprocess.call(paint)


subprocess.call만이 바로 그림판을 실행해주고 나머지들은 전부 cmd를 열고 그 쉘을 통해 명령을 수행시켜준다.


만약 내가 어떤 외부 파일을 실행하고자 한다면??

그게 잠깐 구동되고 종료되는 거라면야 뭐 cmd도 같이 종료가 되니 크게 문제될 것은 없겠지만...


위와 같이 아예 창을 띄우는 프로그램을 구동시켜야 하는 경우에는 얘기가 달라진다.

창이 띄워져 있는 동안은 cmd도 같이 부모 프로세스로 메모리를 잡아 먹기 때문이다.

(subprocess 역시도 cmd는 안 띄우지만 python.exe가 부모 프로세스로서 메모리를 잡아먹게 된다.)


이럴 때는 Windows API인 ShellExecuteA 나 ShellExecuteEx 메소드들을 이용해주면 나을 듯 하다.

Windows API이기 때문에 파이썬에서는 ctypes 모듈을 이용하여 사용할 수 있다.


예제에서는 ShellExecuteA 만을 사용해보도록 한다.

(솔직히 ShellExecuteEx 함수는 아직 인자값이 뭘 뜻하는지 제대로 잘 안 알아봤다. -_-)


이 놈은 스레드를 별도로 구현해줄 필요도 없다. 그냥 바로 한 방에 다 써주면 됨.


import ctypes

calc = ("c:\windows\system32\\calc.exe")
notepad = ("c:\windows\system32\\notepad.exe")
paint = ("c:\windows\system32\\mspaint.exe")

ctypes.windll.shell32.ShellExecuteA(0, 'open', calc, None, None, 1)
ctypes.windll.shell32.ShellExecuteA(0, 'open', notepad, None, None, 1)
ctypes.windll.shell32.ShellExecuteA(0, 'open', paint, None, None, 1)



해당 메소드의 MSDN 문서 링크는 다음과 같으며 사용되는 인자 값은 각자 체크하도록... -_-


https://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx






[그림. 2] 도스 쉘을 통하지 않고 바로 실행


3개의 프로그램 모두 독립적으로 실행이 되었다.

실제 Process Monitoring 툴을 이용하여 확인을 해봐도 cmd.exe의 반응은 전혀 일어나지 않고, 부모 프로세스 없이

독립적으로 실행이 되기 때문에 외부의 어떤 파일을 구동하기 위한 작업에는 가장 적합하지 않을까 싶다.






블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

연습 삼아 만들고 있는 혼자 쓸 툴에서 jpeg 이미지의 크기를 줄여야 하는 상황이 발생해서 검색을 해보다가

파이썬 2.7.x 인지 3.x인지 얘기도 없고 코드들을 보면 맞지 않는 것들도 좀 있고 그래서 답답하던 찰나...

(stackoverflow.com 사이트도 암튼 유저들의 집합이라 잘못된 정보 많은 듯.. ㅡㅡㅋ)


날이 추워서 계속 검색하기 귀찮아져서 그냥 검색한 2개의 예제문을 보고 코드 해석하고 안 맞는 부분은

유추해서 정리해보니 잘 되었다.


01. from cStringIO import StringIO
02. from PIL import Image
03.
04. file = r'C:\Users\Slays_Desktop\Pictures\logon_img\original.jpg'
05.
06. img = Image.open(file)        # 이미지 파일을 열어서 핸들링 한다. (그냥 open아니고 Image 모듈로 open한다.)
07. buffer = StringIO()              # 리사이징 될 jpg code를 저장해둘 메모리 버퍼를 확보한다.
08. img.save(buffer, 'jpeg', quality=85)        # 이미지를 jpeg 형식으로 85 수준의 퀄리티로 하여 버퍼에 저장한다.
09. buffer.seek(0)                                   # 버퍼의 스트림를 맨 앞으로 땡겨온다.(안 해도 되지만 혹시나...)
10. with open('resize.jpg', 'wb') as nfile:
11. nfile.write(buffer.getvalue())                        # 버퍼 값을 가져와 바이너리 형식으로 파일에 저장시킨다.

(buffer.getvalue()가 버퍼 값을 가져와주는 것)


정리를 따로 자세히 해보려다 그냥 주석으로 코드 옆에 남겨둔다.

검색한 것들에선 11번 줄은 원래 검색해본 것에선 getvalue()가 아니라 무슨 contents() 메소드를 쓰라고 되어 있는데,

내게 그런 메소드 따위 없었다. StringIO 라이브러리나 cStringIO 라이브리러나 다 그런 거 내겐 없었음 ㅠㅠ

getvalue()를 쓰니깐 버퍼에 저장된 내용물을 써먹을 수가 있었다.


그리고 8번째 줄의 quailty 부분 얘긴데, 저것에 넣는 수치가 % 인 것 같은데, 100 수치를 줘도 원본과 이미지의 크기가 똑같지는 않다. 뭐 거~~의 용량의 차이가 크진 않는데, 이미지 프로세싱의 구조적 문제 때문에 미세하게 다른 것이겠지!

암튼 수치를 줄여주면 JPEG 포맷의 파일은 이미지 용량이 줄어든다.


또 웃긴 건 바이너리 파일을 다루는 것인데 저장될 파일을 만들 때 wb 로 오픈해야 하는 걸

w로만 하라고 검색되더라. w로 오픈한 파일에 코드들을 저장시키면 jpg 이미지 다 깨진다.


머 암튼 저장한 이미지의 사이즈는 저런 차이를 보였다. (quailty 85% 짜리를 줄 때의 용량 차이다.)




[그림. 1] 원본과 리사이징 사진


- original.jpg : 1,056,382 byte

- resize.jpg : 224,238 byte




참고로 라이브러리에 대한 얘기를 잠깐 하자면


cStringIO은 StringIO의 형제? 급인 모듈이며 그 넘과 비슷한 기능을 제공해준다고 나오는데

cStringIO가 그냥 StringIO 보다 속도적인 면에서 더 낫다고 카더라(통신이 있었음) 그래서 난 cStringIO 씀.


StringIO에 대한 구글신의 번역은 다음과 같다. (cString도 기능적인 면은 이와 대동소이하다고 했었음.)


"이 모듈은 문자열 버퍼 (메모리 파일이라고도 함)를 읽고 쓰는 파일과 비슷한 클래스 인 StringIO를 구현합니다."

(메모리를 이용하니 당연히 속도가 더 빠르겠지)


아무튼 저렇게 하면 JPEG 파일의 이미지를 불러와 용량을 줄인 후에 새롭게 저장을 시킬 수가 있게 된다.


만약 저장할 이미지의 사이즈 정보를 미리 알려면??


버퍼에 저장된 값을 가져오면서 동시에 __len__() 메소드를 이용해주면 되겠다.


buffer.getvalue().__len__()


이렇게 해주면 int 형으로 용량의 값을 알려준다. 출력을 하건 어딘가 변수로 넣어서 활용하건 그건 유저의 몫임.


블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

wxpython을 사용해서 윈도우 창 (프레임)의 스타일을 지정해줄 때에 사용하는 기본은 다음과 같다.


import wx

app = wx.App()
frame = wx.Frame(None, -1, 'frame test', style=wx.DEFAULT_FRAME_STYLE)
frame.Show()
app.MainLoop()


윈도우의 창을 띄우기 위해 사용되는 아주 기본이 되는 코드이고 실행 결과는 다음과 같다.




[그림. 1] 기본 Frame의 모습





위 코드의 2번 째 줄의 인자값들이 바로 윈도우 창을 구성하는 요소가 되는데,

창의 사이즈를 고정시킨다거나 또는 최소, 최대, 종료 버튼 등을 활성화 또는 비활성화를 시키고 싶어서

검색을 해봤는데....


윈도우 창의 기본 프레임을 구성하는 건 wx.DEFAULT_FRAME_STYLE 라는 인자였었고,

그 인자값 하나로 아래의 모든 값들이 표현(Enable)되는 것이었다.


wx.MINIMIZE_BOX : 최소화 버튼


wx.MAXIMIZE_BOX  : 최대화 버튼


wx.RESIZE_BORDER : 창 크기 조절 가능


wx.SYSTEM_MENU : 이건 나도 모르겠음. 검색하면 나오겠지만 필요가 없어서 패스 -_-


wx.CAPTION : 상단바 (타이틀과 최소/최대/종료 버튼이 있는 바를 의미한다.)


wx.CLOSE_BOX : 종료 버튼


wx.CLIP_CHILDREN : 이것도 잘 모르겠음 귀찮아서 검색 안 함 -_-



디폴트 프레임 하나만 선언하면 저것들이 다 Enable 되는 것이다.

근데 만약 저 것들 중 일부를 Disable 시키고 싶다면??


우선 wx.DEFAULT_FRAME_STYLE를 먼저 선언하고 그 뒤에 연이어서 배제 할 스타일을 선언해주면 된다.

뭐 코딩하는 사람에 따라서 디폴트 프레임을 안 쓰고, 그냥 7개의 선언부 중 원하는 것만 선언해도 될 것이다.


나는 창의 사이즈 조절과 최대화 버튼을 Disable 시키고 싶었다.


frame = wx.Frame(None, -1, 'frame test', style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX)


위 코드에서 ^ 기호는 제외를 하겠다는 기호이다.

만약 제외가 아닌 추가를 시키고 싶다면 | 기호를 써주면 된다. (응용은 알아서 jal~~~)




[그림. 2] 최대화 버튼과 리사이징 비활성화


아무튼 보면은 마우스로 리사이징은 되지 않으며 최대화 버튼 또환 비활성화가 되었다.


개인적으로 작은 툴을 만들었었는데 최대화가 필요 없던지라 기능을 알아보다가 한글로 된 사이트가 없어 보여서 기록해둔다.

(한글로 누군가 옮겨 둔 것을 내가 검색 못했었을지도.. -_-)

블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

파이썬을 exe 파일로 빌드하기 위해서는 py2exe 라는 플러그인이 필요하다.

근데 요놈이 x86 파일은 잘 뽑아내는데 x64 파일은 뽑아내다가 에러를 토하시니...


다른 걸 알아보고 알아보다가 pyinstaller 라는 녀석을 발견하게 되었다.


뭐 사용 방법에 대해서는 검색하면 엄청 많이 나온다.

굳이 여기에 다 열거하긴 귀찮고, 설치 부터 사용법 까지 대략 잘 정리해놓으신 분의 블로그 주소를 링크해본다.


http://m.blog.naver.com/mandori21/220372958993



그런데 왜 이 글을 쓰기 시작했냐면 현재 Pyinstaller 는 개발자 용 버전까지 해서 3.3xxxx 까지 업데이트 되어 있다.

문제점을 몇 가지 기록해두기 위해서 글을 작성해본다.


개인적으로 사용하는 몇 가지에 대해서만 열거해둔다. 왜냐하면 내가 까먹으면 곤란하니깐... ㅡㅡㅋ

(기록 만큼 좋은 것도 없..)


그리고 3.3 버전 이하에서 발생하는 문제점도 같이 적어두도록 한다.



1. pyinstaller 또한 py2exe 처럼 그냥 exe로 빌드해버리면 여러 파일로 쪼개져버린다.

   파이썬으로 제작한 파일을 외부에 배포할 경우는 보통 exe 단일 파일로 묶게 되는데,

   그 때 사용되는 인자값이 -F 이다.
   sample.py 라는 파일이 sample.exe 파일 하나로 묶이게 된다.

   (압축 방식으로 묶이기 때문에 실행 시 압축을 푸는 딜레이가 미세하게 발생한다.)


 ex) pyinstaller.exe -F sample.py



2. exe 파일 실행 시 콘솔(도스창) 화면을 나타내고 싶지 않을 경우에는 아래의 인자값을 사용한다.

   총 세 가지 방법이 있는데 한 가지만 사용해주면 된다.


 ex) pyinstaller.exe -w sample.py

 ex) pyinstaller.exe --noconsole sample.py

 ex) pyinstaller.exe --windowed sample.py



3. 빌드된 실행 파일이 관리자 권한을 요구하도록 실행하기 위한 인자 값은 다음과 같다. 이것을 이용하면 굳이 파이썬      코드 내에서 권한 상승을 요청시키는 뻘짓을 하지 않아도 된다.
   stackoverflow 사이트 등에 나오는 (내 블로그에도 권한 상승에 대한 글이 있다.) 내용은 자기가 자기 자신을 권한 상승
   하여 실행을 요청하는 짓을 한다. 즉, 프로세스가 중복되어 실행되므로 괜한 메모리 낭비가 발생한다.
   

 ex) pyinstaller.exe --uac-admin sample.py


중요한 언급을 한다. 해당 옵션은 exe 단일 파일로 묶는 -F 인자랑 같이 쓰면 그 효력을 잃는다.

   아니.. 효력이 발생하지 않는다고 해야 하겠지. 이게 참 맘에 안드는 버그... 

   -F를 사용하지 않으면 파일이 여러개로 쪼개어 생성되겠지만 정작 메인 exe 파일은 관리자 권한 요청이

   기본으로 적용된다.

   만약 빌드하고 싶은 파일이 x64 가 아닌 x86 이라면 굳이 pyinstaller 말고 py2exe를 사용하기 바란다.

   왜냐하면 py2exe는 단일 파일로 빌드할 때도 UAC가 잘 적용되기 때문이다.


4. 빌드 파일에 아이콘을 적용하고 싶을 경우는 다음의 인자값을 이용한다. 솔직히 이것 때문에 겁나 애먹었다.

   메뉴얼을 제대로 다 정독하지 않은 내 탓이지만.. ㅠㅠ

   인자값 뒤에 파일명을 넣으면 된다고 했는데 죽어도 안 되더라. 메뉴얼을 더 정독해 보니 equal 기호를

   넣어줘야 카더라.

   왜 옵션 리스트에서 바로 안 나오고 한~~~참 뒤의 예제문 페이지에서 그런 설명이나오는게냐 -_-

   옵션은 두 개의 방법을 제공하고 있다.


 ex) pyinstaller.exe --icon=icons\icon.ico sample.py

 ex) pyinstaller.exe -i=icons\icon.ico sample.py


위의 인자값은 icons 폴더 안에 있는 icon.ico 파일을 사용한다는 의미이다. 위 예제문의 경우 .py 파일과 같은

   경로에 icons 폴더가 있는 것이다. 만약 완전 다른 경로라면 full path를 적용시키면 될 것이다.


ico 파일 외에도 icon이 리소스에 적용되어 있는 exe 파일을 사용해도 된다.

   저렇게 하면 빌드된 exe 파일의 리소스 영역에 아이콘의 이미지가 저장이 된다.

   자~ 그렇다면 여기서 잠깐, py 파일이 만약 GUI 프로그램의 소스라고 가정하고 그 GUI 화면에 윈도우의

   '제목 표시줄' 있다면?? 제목 표시줄에는 보통 프로그램의 아이콘 이미지와 프로그램의 이름이 표기가 되겠지!!?

   그럼 exe로 빌드 하기 전에 그 GUI 코드에서의 아이콘 참조 위치는 생성될 exe 자기 자신이 되도록 하면 될 것이다.

   (sys.argv 메소드와 os.path.basename 메소드를 잘 사용해보자.)


   실수로 py 파일 내에서 똑같이 icon.ico 파일을 참조하도록 해버려두니 정작 py 파일을 그냥 돌릴 땐 잘 됐었지만

   exe로 빌드된 파일은 아이콘 못 찾겠다 꾀꼬리를 외치게 되더라.


   pyinstaller는 exe 파일의 아이콘만 변경시켜줄 뿐이지 GUI 상의 아이콘을 신경써줄리 없으니 혼동하지 말자.

   물론 빌드한 폴더 내에 icon 폴더를 수동으로 넣어줄 수는 있겠지만, 그렇게 하는 것은 불필요한 짓일 뿐...

   어차피 빌드된 exe 자체에 아이콘 리스소가 들어가 있으니 자기 자신을 참조시키는 것이 더 나을 것이다.



내가 좀 헤맨 부분이 아마 저 정도 쯤 되는 듯 하다.

기록 끝~


블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/109496


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.





[wxPython] wx.CheckBox를 이용한 체크박스 만들기



# -*- coding: cp949 -*-
#!/usr/bin/python

# checkbox.py


import wx


class MyCheckBox(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 170))

        panel = wx.Panel(self, -1)
        # 체크박스 생성
        self.cb = wx.CheckBox(panel, -1, 'Show Title', (10, 10))
        self.cb.SetValue(True)

        # 체크박스 이벤트 연결
        wx.EVT_CHECKBOX(self, self.cb.GetId(), self.ShowTitle)

        self.Show()
        self.Centre()

    def ShowTitle(self, event):
        if self.cb.GetValue():
            self.SetTitle('checkbox.py')
        else: self.SetTitle('')


app = wx.App(0)
MyCheckBox(None, -1, 'checkbox.py')
app.MainLoop()

[실행 화면]




블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/107312


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.





[wxPython] wx.ComboBox(콤보 박스)를 사용법 및 이벤트 처리



# -*- coding: cp949 -*-
#!/usr/bin/python

# combobox.py

import wx


class MyDialog(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title, size=(250, 270))

        panel = wx.Panel(self, -1, (75, 20), (100, 127),  style=wx.SUNKEN_BORDER)
        # StaticBitmap 생성
        self.picture = wx.StaticBitmap(panel)
        
        panel.SetBackgroundColour(wx.WHITE)

        # 이미지 리스트 
        self.images = ['tolstoy.jpg', 'feuchtwanger.jpg', 'pasternak.jpg', 'galsworthy.jpg', 'wolfe.jpg', 'zweig.jpg']
        
        authors = ['Leo Tolstoy', 'Lion Feuchtwanger', 'Boris Pasternak', 'John Galsworthy', 'Tom Wolfe', 'Stefan Zweig' ]

       # 콤보 박스 생성
        wx.ComboBox(self, -1, pos=(50, 170), size=(150, -1), choices=authors, style=wx.CB_READONLY)
        wx.Button(self, 1, 'Close', (80, 220))

        self.Bind(wx.EVT_BUTTON, self.OnClose, id=1)
        self.Bind(wx.EVT_COMBOBOX, self.OnSelect)

        self.Centre()

    def OnClose(self, event):
        self.Close()


    # 콤보 박스 이벤트 처리
    def OnSelect(self, event):
        # 콤보 박스에서 선택한 아이템을 얻음.
        item = event.GetSelection()
        self.picture.SetFocus()
       # 선택한 항목에 해당하는 이미지를 로드함.
        self.picture.SetBitmap(wx.Bitmap('images/' + self.images[item]))


class MyApp(wx.App):
    def OnInit(self):
        dlg = MyDialog(None, -1, 'combobox.py')
        dlg.ShowModal()
        dlg.Destroy()
        return True

app = MyApp(0)
app.MainLoop()

[실행 화면]




블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/107288


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.





[wxPython] wx.StaticBox를 이용한 컨트롤 그룹만들기



# -*- coding: cp949 -*-
#!/usr/bin/python

# staticbox.py

import wx

class MyDialog(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title, size=(260, 250))
        
        # StaticBox 생성
        wx.StaticBox(self, -1, 'Personal Info', (5, 5), size=(240, 170))
        
        wx.CheckBox(self, -1 ,'Male', (15, 30))
        wx.CheckBox(self, -1 ,'Married', (15, 55))
        wx.StaticText(self, -1, 'Age', (15, 95))
        wx.SpinCtrl(self, -1, '1', (55, 90), (60, -1), min=1, max=120)
        wx.Button(self, 1, 'Ok', (90, 185), (60, -1))

        self.Bind(wx.EVT_BUTTON, self.OnClose, id=1)

        self.Centre()
        self.ShowModal()
        self.Destroy()

    def OnClose(self, event):
        self.Close()

app = wx.App(0)
MyDialog(None, -1, 'staticbox.py')
app.MainLoop()

[실행 화면]




블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/107269


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.





[wxPython] wx.StaticText를 이용한 문자열 출력



# -*- coding: cp949 -*-
#!/usr/bin/python

# statictext.py

import wx


class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(320, 350))

        lyrics1 = '''I'm giving up the ghost of love
                    in the shadows cast on devotion
                    She is the one that I adore
                    creed of my silent suffocation
                    Break this bittersweet spell on me
                    lost in the arms of destiny'''

        lyrics2 = '''There is something in the way
                    You're always somewhere else
                    Feelings have deserted me
                    To a point of no return
                    I don't believe in God
                    But I pray for you'''

        panel = wx.Panel(self, -1)
        
        # StaticText를 이용한 문자열 출력
        wx.StaticText(panel, -1, lyrics1, (45, 25), style=wx.ALIGN_CENTRE)
        wx.StaticText(panel, -1, lyrics2, (45, 190), style=wx.ALIGN_CENTRE)
        self.Centre()

class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, 'statictext.py')
        frame.Show(True)
        self.SetTopWindow(frame)
        return True


app = MyApp(0)
app.MainLoop()

[실행 화면]




블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/106918


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.



출처: http://slays.tistory.com/35 [Reverse Engineering]





[wxPython] wx.StaticLine 을 이용한 구분선 추가



# -*- coding: cp949 -*-
#!/usr/bin/python

# centraleurope.py


import wx

class MyDialog(wx.Dialog):
    def __init__ (self, parent, ID, title):
        wx.Dialog.__init__(self, parent, ID, title, size=(360, 370))

        font = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)
        heading = wx.StaticText(self, -1, 'The Central Europe', (130, 15))
        heading.SetFont(font)

        # StaticLine 추가
        wx.StaticLine(self, -1, (25, 50), (300,1))

        wx.StaticText(self, -1, 'Slovakia', (25, 80), style=wx.ALIGN_RIGHT)
        wx.StaticText(self, -1, 'Hungary', (25, 100), style=wx.ALIGN_RIGHT)
        wx.StaticText(self, -1, 'Poland', (25, 120), style=wx.ALIGN_RIGHT)
        wx.StaticText(self, -1, 'Czech Republic', (25, 140))
        wx.StaticText(self, -1, 'Germany', (25, 160))
        wx.StaticText(self, -1, 'Slovenia', (25, 180))
        wx.StaticText(self, -1, 'Austria', (25, 200))
        wx.StaticText(self, -1, 'Switzerland', (25, 220))

        wx.StaticText(self, -1, '5 379 000', (250, 80))
        wx.StaticText(self, -1, '10 084 000', (250, 100))
        wx.StaticText(self, -1, '38 635 000', (250, 120))
        wx.StaticText(self, -1, '10 240 000', (250, 140))
        wx.StaticText(self, -1, '82 443 000', (250, 160))
        wx.StaticText(self, -1, '2 001 000', (250, 180))
        wx.StaticText(self, -1, '8 032 000', (250, 200))
        wx.StaticText(self, -1, '7 288 000', (250, 220))

        # StaticLine 추가
        wx.StaticLine(self, -1, (25, 260), (300,1))

        sum = wx.StaticText(self, -1, '164 102 000', (240, 280))
        
        # 현재 폰트 정보 변경
        sum_font = sum.GetFont()     
        sum_font.SetWeight(wx.BOLD)
        sum.SetFont(sum_font)

        wx.Button(self, 1, 'Ok', (140, 310), (60, 30))

        self.Bind(wx.EVT_BUTTON, self.OnOk, id=1)
        self.Centre()

    def OnOk(self, event):
        self.Close()

class MyApp(wx.App):
    def OnInit(self):
        dia = MyDialog(None, -1, 'centraleurope.py')
        dia.ShowModal()
        dia.Destroy()
        return True


app = MyApp()
app.MainLoop()

[실행 화면]




블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요



본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/106883


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.




[wxPython] wx.BitmapButton의 사용



# -*- coding: cp949 -*-

#!/usr/bin/python

# player.py

import wx


class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(350, 300))
        
        panel = wx.Panel(self, -1) 
        # 화면용 패널
        pnl1 = wx.Panel(self, -1)
        pnl1.SetBackgroundColour(wx.BLACK)
        # 컨트롤 배치 패널 생성
        pnl2= wx.Panel(self, -1 )
        
        # 메뉴바 생성
        menubar = wx.MenuBar()
        # 메뉴들 생성
        file = wx.Menu()
        play = wx.Menu()
        view = wx.Menu()
        tools = wx.Menu()
        favorites = wx.Menu()
        help = wx.Menu()

        file.Append(101, '&quit', 'Quit application')
        menubar.Append(file, '&File')
        menubar.Append(play, '&Play')
        menubar.Append(view, '&View')
        menubar.Append(tools, '&Tools')
        menubar.Append(favorites, 'F&avorites')
        menubar.Append(help, '&Help')

       # 슬라이더1 생성
        slider1 = wx.Slider(pnl2, -1, 0, 0, 1000)
        
        # Bitmap  버튼 생성
        pause = wx.BitmapButton(pnl2, -1, wx.Bitmap('icons/stock_media-pause.png'))
        play  = wx.BitmapButton(pnl2, -1, wx.Bitmap('icons/stock_media-play.png'))
        next  = wx.BitmapButton(pnl2, -1, wx.Bitmap('icons/stock_media-next.png'))
        prev  = wx.BitmapButton(pnl2, -1, wx.Bitmap('icons/stock_media-prev.png'))
        volume = wx.BitmapButton(pnl2, -1, wx.Bitmap('icons/volume.png'))
        
        # 슬라이더2 생성
        slider2 = wx.Slider(pnl2, -1, 0, 0, 100, size=(120, -1))

        
        vbox = wx.BoxSizer(wx.VERTICAL)
        # 슬라이더 박스 생성
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
       # 컨트롤 버튼 박스 생성
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)

       # 생성한 박스들에 컨트롤 배치
        hbox1.Add(slider1, 1)
        hbox2.Add(pause)
        hbox2.Add(play, flag=wx.RIGHT, border=5)
        hbox2.Add(next, flag=wx.LEFT, border=5)
        hbox2.Add(prev)
        hbox2.Add((150, -1), 1, flag=wx.EXPAND | wx.ALIGN_RIGHT)
        hbox2.Add(volume, flag=wx.ALIGN_RIGHT)
        hbox2.Add(slider2, flag=wx.ALIGN_RIGHT | wx.TOP | wx.LEFT, border=5)

        # 컨트롤 배치가 끝난 박스들을 컨트롤 패널에 설정 
        vbox.Add(hbox1, 1, wx.EXPAND | wx.BOTTOM, 10)
        vbox.Add(hbox2, 1, wx.EXPAND)
        pnl2.SetSizer(vbox)
       
        # 화면패널과 컨트롤 패널을 배치할 박스 생성

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(pnl1, 1, flag=wx.EXPAND)
        sizer.Add(pnl2, flag=wx.EXPAND | wx.BOTTOM | wx.TOP, border=10)

        # 최소 사이즈 설정
        self.SetMinSize((350, 300))
        # 메뉴바 설정
        self.SetMenuBar(menubar)
        # 상태바 생성
        self.CreateStatusBar()
        # 프레임에 박스 셋팅
        self.SetSizer(sizer)
        self.Centre()

class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, 'Player')
        frame.Show(True)
        self.SetTopWindow(frame)
        return True


app = MyApp(0)
app.MainLoop()

[실행 화면]




블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/106147


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.




[wxPython] wx.Button를 이용한 Button 이벤트 처리 와 랜덤 숫자 추출


# -*- coding: cp949 -*-
#!/usr/bin/python

# buttons.py

import wx
# 랜덤 처리 유닛
import random


# Dialog 사이즈
APP_SIZE_X = 300
APP_SIZE_Y = 200


class MyButtons(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title, size=(APP_SIZE_X, APP_SIZE_Y))

       # 버튼 생성
        wx.Button(self, 1, 'Close', (50, 130))
        wx.Button(self, 2, 'Random Move', (150, 130), (110, -1))

        # 버튼 이벤트 함수 연결
        self.Bind(wx.EVT_BUTTON, self.OnClose, id=1)
        self.Bind(wx.EVT_BUTTON, self.OnRandomMove, id=2)

        self.Centre()
        self.ShowModal()
        self.Destroy()


   # 닫기 이벤트 처리 함수
    def OnClose(self, event):
        self.Close(True)


    # 랜덤 이동 이벤트 처리 함수
    def OnRandomMove(self, event):
        # 스크린 사이즈를 구함.
        screensize = wx.GetDisplaySize()
        # 랜덤하기 위치값을 구함
        randx = random.randrange(0, screensize.x - APP_SIZE_X) # X
        randy = random.randrange(0, screensize.y - APP_SIZE_Y) # Y
       # Frame 이동
        self.Move((randx, randy))


app = wx.App(0)
MyButtons(None, -1, 'buttons.py')
app.MainLoop()

[실행 화면]




블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/104212


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.



[wxPython] 다이얼로그(Dialog) 만들기2





# -*- coding: cp949 -*-
#!/usr/bin/python

# customdialog2.py


import wx


class MyDialog(wx.Dialog):
    # 다이얼 로그 초기화
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title)
        vbox = wx.BoxSizer(wx.VERTICAL)
        stline = wx.StaticText(self, 11, 'Discipline ist Macht.')
        vbox.Add(stline, 1, wx.ALIGN_CENTER|wx.TOP, 45)
        # ButtonSizer 생성( NO, YES, HELP )
        sizer =  self.CreateButtonSizer(wx.NO|wx.YES|wx.HELP)
        vbox.Add(sizer, 0, wx.ALIGN_CENTER)
        self.SetSizer(vbox)
        # 버튼 이벤트 연결
        self.Bind(wx.EVT_BUTTON, self.OnYes, id=wx.ID_YES)


    # YES 버튼 이벤트 처리
    def OnYes(self, event):
        self.Close()


class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)
        panel = wx.Panel(self, -1)
        wx.Button(panel, 1, 'Show custom Dialog', (50,50))
        # 'Show Custom Dialog' 버튼 이벤트 연결
        self.Bind(wx.EVT_BUTTON, self.OnShowCustomDialog, id=1)


    # 이벤트 처리 함수
    def OnShowCustomDialog(self, event):
        # 다이얼로그 생성
        dia = MyDialog(self, -1, '')
        # 다이얼로그 모달로 열기
        val = dia.ShowModal()
        # 다이얼 로그 파괴하기
        dia.Destroy()

class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, 'customdialog2.py')
        frame.Show(True)
        frame.Centre()
        return True

app = MyApp(0)
app.MainLoop()

[실행 화면]




블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/104164

행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.



[wxPython] 다이얼로그(Dialog) 만들기



# -*- coding: cp949 -*-
#!/usr/bin/python
# customdialog1.py


import wx

class MyDialog(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title, size=(350,300))
        # 다이얼 로그 구성 처리
        sizer =  self.CreateTextSizer('My Buttons')
        sizer.Add(wx.Button(self, -1, 'Button'), 0, wx.ALL, 5)
        sizer.Add(wx.Button(self, -1, 'Button'), 0, wx.ALL, 5)
        sizer.Add(wx.Button(self, -1, 'Button'), 0, wx.ALL, 5)
        sizer.Add(wx.Button(self, -1, 'Button'), 0, wx.ALL|wx.ALIGN_CENTER, 5)
        sizer.Add(wx.Button(self, -1, 'Button'), 0, wx.ALL|wx.EXPAND, 5)
        self.SetSizer(sizer)

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(550,500))

        panel = wx.Panel(self, -1)
        wx.Button(panel, 1, 'Show Custom Dialog', (100,100))
        # 버튼 이벤트 연결
        self.Bind (wx.EVT_BUTTON, self.OnShowCustomDialog, id=1)

    # 버튼 이벤트 처리 함수
    def OnShowCustomDialog(self, event):
        # 다이얼로그 생성
        dia = MyDialog(self, -1, 'buttons')
        # 모달 처리
        dia.ShowModal()
        # 다이얼로그 파괴하기
        dia.Destroy()


class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, 'customdialog1.py')
        frame.Show(True)
        frame.Centre()


        return True

app = MyApp(0)
app.MainLoop()

[실행 화면]



블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/104082


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.




[wxPython] 이벤트05 (사이즈 이벤트 예제 : wx.EVT_KEY_DOWN)



# -*- coding: cp949 -*-
#!/usr/bin/python

# keyevent.py

import wx

class KeyEvent(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)
        panel = wx.Panel(self, -1)
        # 키누름 이벤트 연결
        panel.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
        panel.SetFocus()

        self.Centre()
        self.Show(True)


    # 키보드 키눌림 이벤트 처리 함수
    def OnKeyDown(self, event):
        # 이벤트 발생시 키코드 값을 얻음.
        keycode = event.GetKeyCode()
        # 이벤트 키가 ESC일 경우
        if keycode == wx.WXK_ESCAPE:
            # 메시지 박스 띄움
            ret  = wx.MessageBox('Are you sure to quit?', 'Question', wx.YES_NO | wx.CENTRE |
                                     wx.NO_DEFAULT, self)
            # 메시지 박스에서 YES 버튼을 눌렀다면
            if ret == wx.YES:
                #프로그램 종료
                self.Close()
        # 누른 키가 ESC키가 아닐 경우
        event.Skip()

app = wx.App()
KeyEvent(None, -1, 'keyevent.py')
app.MainLoop()



[실행화면]






블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/104069


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.



[wxPython] 이벤트04 (사이즈 이벤트 예제 : wx.EVT_PAINT)



# -*- coding: cp949 -*-

#!/usr/bin/python
# paintevent.py

import wx

class PaintEvent(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)
        # Paint 이벤트 함수와 연결
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Centre()

    # Paint 이벤트 처리함수
    def OnPaint(self, event):
        # 벨 울리기
        wx.Bell()


class MyApp(wx.App):
    def OnInit(self):
        pe = PaintEvent(None, -1, 'paintevent.py')
        pe.Show(True)
        return True

app = MyApp(0)
app.MainLoop()



[실행화면]


마우스로 창의 크기를 변경할 때 마다 벨 소리가 발생한다.



블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/104036


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.



[wxPython] 이벤트03 (사이즈 이벤트 예제 : wx.EVT_SIZE)




#!/usr/bin/python
# -*- coding: cp949 -*-
# moveevent.py

import wx


class MoveEvent(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)
        # 좌표값 출력 라벨 구성
        wx.StaticText(self, -1, 'x:', (10,0))
        wx.StaticText(self, -1, 'y:', (10,20))
        self.st1 = wx.StaticText(self, -1, '', (30, 0))
        self.st2 = wx.StaticText(self, -1, '', (30, 20))
        
        # 이동 이벤트 연결
        self.Bind(wx.EVT_MOVE, self.OnMove)
        self.Centre()

    # 이동 이벤트 처리 함수
    def OnMove(self, event):
        # 이벤트 발생시 현재 윈도우의 위치값을 구함.
        x, y = event.GetPosition()
        # 좌표값 셋팅
        self.st1.SetLabel(str(x))
        self.st2.SetLabel(str(y))

class MyApp(wx.App):
    def OnInit(self):
        me = MoveEvent(None, -1, 'moveevent.py')
        me.Show(True)
        return True

app = MyApp(0)
app.MainLoop()


[실행화면]




블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요

본 내용의 출처는 이글루 블로그의 '하린아빠' 라는 네임을 쓰시는 분의 블로그입니다.

[출처] - http://pythondev.egloos.com/104016


행여나 이글루 블로그가 없어지면 참고할 곳이 사라지기에 주인장님께 댓글을 남기고 퍼 옵니다.


[wxPython] 이벤트02 (사이즈 이벤트 예제 : wx.EVT_SIZE)





#!/usr/bin/python
# -*- coding: cp949 -*-
# sizeevent.py

import wx


class SizeEvent(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)
        # 사이즈 조정 이벤트 연결
        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.Centre()

    # 사이즈 조정 이벤트 처리함수
    def OnSize(self, event):
        # 타이틀에 이벤트 발생시 사이즈를 구하여 표시해준다.
        self.SetTitle(str(event.GetSize()))


class MyApp(wx.App):
    def OnInit(self):
        se = SizeEvent(None, -1, 'sizeevent.py')
        se.Show(True)
        return True


app = MyApp(0)
app.MainLoop()


[실행화면]



블로그 이미지

slays

생각나는 것, 알게된 것을 끄적여보자.

댓글을 달아 주세요