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

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


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




[wxPython] wx.ManuBar 만들기(체크, 라디오, 서브 매뉴)



#!/usr/bin/python

# menu1.py

import wx

class MyMenu(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(200, 150))

        # menubar 생성
        menubar = wx.MenuBar()
        # file 메뉴 생성
        file = wx.Menu()
        # edit 메뉴 생성
        edit = wx.Menu()
        # help 메뉴 생성
        help = wx.Menu()
        # file / Open 추가
        file.Append(101, '&Open', 'Open a new document')
        # file / Save 추가
        file.Append(102, '&Save', 'Save the document')
        # file에 구분선 추가
        file.AppendSeparator()
        # quit 메뉴 아이템 생성
        quit = wx.MenuItem(file, 105, '&Quit\tCtrl+Q', 'Quit the Application')
        # quit 메뉴에 Bitmap 아이콘 추가 (ConvertToBitmap -> png를 bitmap으로 변경)
        quit.SetBitmap(wx.Image('icons/stock_exit-16.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap())
        # file / Quit 추가
        file.AppendItem(quit)
        # edit 메뉴 추가(CheckBox 형식)
        edit.Append(201, 'check item1', '', wx.ITEM_CHECK)
        edit.Append(202, 'check item2', kind=wx.ITEM_CHECK)
        # submenu 생성
        submenu = wx.Menu()
        # submenu 추가(Radio 형식)
        submenu.Append(301, 'radio item1', kind=wx.ITEM_RADIO)
        submenu.Append(302, 'radio item2', kind=wx.ITEM_RADIO)
        submenu.Append(303, 'radio item3', kind=wx.ITEM_RADIO)
        # edit menu에 submenu 추가
        edit.AppendMenu(203, 'submenu', submenu)

        # menubar에 생성한 menu들을 추가함
        menubar.Append(file, '&File')
        menubar.Append(edit, '&Edit')
        menubar.Append(help, '&Help')
        # menubar 셋팅
        self.SetMenuBar(menubar)
        # 중앙 정렬
        self.Center()
        # 105번 메뉴를 OnQuit 이벤트 함수와 연결
        self.Bind(wx.EVT_MENU, self.OnQuit, id=105)

        # 상태바를 생성한다.
        self.CreateStatusBar()


    # Quit 이벤트 함수

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


class MyApp(wx.App):
    def OnInit(self):
        # menu를 가진 frame 생성
        frame = MyMenu(None, -1, 'menu1.py')
        frame.Show(True)
        return True

app = wx.App()
mainapp = MyApp(app)
mainapp.MainLoop()

[실행 결과]



블로그 이미지

slays

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

댓글을 달아 주세요

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

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


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





[wxPython] wx.MenuBar를 이용한 메뉴 만들기(기본)



#!/usr/bin/python

# menu1.py

import wx

# menu 클래스 정의

class MyMenu(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(200, 150))

       # menubar 생성
        menubar = wx.MenuBar()
        # file 메뉴 생성
        file = wx.Menu()
        # edit 메뉴 생성
        edit = wx.Menu()
        # help 메뉴 생성
        help = wx.Menu()
        # file / Open 추가
        file.Append(101, '&Open', 'Open a new document')
       # file / Save 추가
        file.Append(102, '&Save', 'Save the document')
        # file에 구분선 추가
        file.AppendSeparator()
       # quit 메뉴 아이템 생성
        quit = wx.MenuItem(file, 105, '&Quit\tCtrl+Q', 'Quit the Application')
       # quit 메뉴에 Bitmap 아이콘 추가 (ConvertToBitmap -> png를 bitmap으로 변경)
        quit.SetBitmap(wx.Image('icons/stock_exit-16.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap())
       # file / Quit 추가
        file.AppendItem(quit)

        # menubar에 생성한 menu들을 추가함
        menubar.Append(file, '&File')
        menubar.Append(edit, '&Edit')
        menubar.Append(help, '&Help')
        # menubar 셋팅
        self.SetMenuBar(menubar)
        # 상태바를 생성한다.
        self.CreateStatusBar()

class MyApp(wx.App):
    def OnInit(self):
        # menu를 가진 frame 생성
        frame = MyMenu(None, -1, 'menu1.py')
        frame.Show(True)
        return True


app = wx.App()
mainapp = MyApp(app)
mainapp.MainLoop()



[실행 결과]



블로그 이미지

slays

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

댓글을 달아 주세요

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

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


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




[wxPython] wx.Frame 아이콘 설정하기


#!/usr/bin/python

# icon.py

import wx


# main 함수 정의
def main():
    app = wx.App()
    frame = wx.Frame(None, title='icon', pos=(350, 300))
    # ICON 설정하기
    frame.SetIcon(wx.Icon('icons/tipi.ico', wx.BITMAP_TYPE_ICO))
    frame.Center()
    frame.Show()
    app.MainLoop()

if __name__ == '__main__':
    # main() 호출
    main()


[실행 결과]



 

블로그 이미지

slays

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

댓글을 달아 주세요

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

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


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




[wxPython] wxFrame::wxFrame 생성하기(생성자)

wxFrame::wxFrame

wxFrame()

기본 생성자.

[예제 1] 기본 모양의 Frame 생성시
         wx.Frame(wx.Window parent, id, string title,
         wx.Point pos = wx.DefaultPosition, wx.Size size = wx.DefaultSize,
         style = wx.DEFAULT_FRAME_STYLE, string name = 'frame')


# Frame 사이즈를 고정하려면 위의 밑줄친 부분을 "style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER" 로 변경하면 된다.



[예제 2] 아이디, 제목, 위치, 크기 지정하여 생성시
         frame = wx.Frame(None, 100, 'Title', wx.Point(100,50), wx.Size(100,100))

[예제 2] 아이디, 제목, 위치, 크기 지정하여 생성시
         frame = wx.Frame(None, 100, 'Title', size = wx.Size(100,100))

[레퍼런스 내용]

wxFrame(wxWindowparentwxWindowID idconst wxStringtitleconst wxPoint& pos = wxDefaultPositionconst wxSize& size = wxDefaultSizelong style = wxDEFAULT_FRAME_STYLEconst wxStringname = "frame")

Constructor, creating the window.

Parameters

parent

      The window parent. This may be NULL. If it is non-NULL, the frame will always be displayed on top of the parent window on Windows.

id

      The window identifier. It may take a value of -1 to indicate a default value.

title

      The caption to be displayed on the frame's title bar.

pos

      The window position. A value of (-1, -1) indicates a default position, chosen by either the windowing system or wxWidgets, depending on platform.

size

      The window size. A value of (-1, -1) indicates a default size, chosen by either the windowing system or wxWidgets, depending on platform.

style

name

      The name of the window. This parameter is used to associate a name with the item, allowing the application user to set Motif resource values for individual windows.

Remarks

For Motif, MWM (the Motif Window Manager) should be running for any window styles to work (otherwise all styles take effect).

See also

wxFrame::Create


wxFrame::~wxFrame

void ~wxFrame()

Destructor. Destroys all child windows and menu bar if present.

블로그 이미지

slays

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

댓글을 달아 주세요

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

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


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



wxWindow
- wxWindow 클래스는 많은 위젯의 기분 클래스로 wxFrame도 wxWindow로 부터 상속 받는다.

[wxFrame을 통해 wxWindow로 부터 상속 받은 몇개의 함수들을 사용하는 예]

#!/usr/bin/python

#simple2.py

import wx


# Application 생성
app = wx.App()


# wxFrame 생성

frame = wx.Frame(None, -1, '')
# frame 툴팁 설정
frame.SetToolTip(wx.ToolTip('This is a frame'))
# frame내에서 적용될 커서 설정
frame.SetCursor(wx.StockCursor(wx.CURSOR_MAGNIFIER))
# frame 위치
frame.SetPosition(wx.Point(0,0))
# frame 크기설정
frame.SetSize(wx.Size(300, 250))
# frame 제목 설정
frame.SetTitle('simple2 title')
# frame을 화면에 출력하기
frame.Show()

# Application 메인 루프
app.MainLoop()


[실행 결과]



블로그 이미지

slays

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

댓글을 달아 주세요

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

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


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



[wxPython] Simple wxPython(초간단 윈도우 띄우기)


#!/usr/bin/python

#simple.py

# wx 라이브러리 포함
import wx

# Application 객체 생성및 wx.App 클래스 초기화
app = wx.App()


# Frame 위젯 생성
frame = wx.Frame(None, -1, 'simple.py')
# Frame 화면에 출력하기
frame.Show()


# Application 메인 루프로 무한 반복하며 이벤트를 받는다.
app.MainLoop()



[실행 결과]



블로그 이미지

slays

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

댓글을 달아 주세요

파이썬의 GUI 를 뭘 쓸까 알아보다가 wxpython이 나은 듯 하여 검색하다 좋은 정보를 발견하여 퍼온다.

혹시나, 행여나, 만약에 해당 사이트가 폐쇄가? 될 경우도 있을 듯 하여 주인장님의 블로그에 퍼가겠다는 의사를 적어놓고 내용 그대로 copy & paste 해옵니다.


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




[wxPython] 미리 정의된 다이얼로그(Dialog)

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

# commondialogs.py

import wx
import os, sys


class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)
        
        self.CreateStatusBar()
        # 메뉴바 생성
        menuBar = wx.MenuBar()
        # 메뉴 추가
        menu = wx.Menu()
        menu.Append(99,  "&Message Dialog", "Shows a Message Dialog")
        menu.Append(100, "&Color Dialog", "Shows a Color Dialog")
        menu.Append(101, "&File Dialog", "Shows a File Dialog")
        menu.Append(102, "&Page Setup Dialog", "Shows a Page Setup Dialog")
        menu.Append(103, "&Font Dialog", "Shows a Font Dialog")
        menu.Append(104, "&Directory Dialog", "Shows a Directory Dialog")
        menu.Append(105, "&SingleChoice Dialog", "Shows a SingleChoice Dialog")
        menu.Append(106, "&TextEntry Dialog", "Shows a TextEntry Dialog")
        menuBar.Append(menu, "&Dialogs")
        # 프레임에 메뉴 셋팅
        self.SetMenuBar(menuBar)
        
        # 메뉴별 이벤트 함수 연결
        self.Bind(wx.EVT_MENU, self.message, id=99)
        self.Bind(wx.EVT_MENU, self.choosecolor, id=100)
        self.Bind(wx.EVT_MENU, self.openfile, id=101)
        self.Bind(wx.EVT_MENU, self.pagesetup, id=102)
        self.Bind(wx.EVT_MENU, self.choosefont, id=103)
        self.Bind(wx.EVT_MENU, self.opendir, id=104)
        self.Bind(wx.EVT_MENU, self.singlechoice, id=105)
        self.Bind(wx.EVT_MENU, self.textentry, id=106)


    # 메세지 다이얼 로그 띄우기
    def message(self, event):
        # 메시지 다이얼로그 생성(이벤트 처리기)
        dlg = wx.MessageDialog(self, 'To save one life is as if you have saved the world.', 'Talmud', wx.OK|wx.ICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()


    # 색상 다이얼 로그 띄우기(이벤트 처리기)
    def choosecolor(self, event):
        # 생상 다이얼로그 생성
        dlg = wx.ColourDialog(self)
        # 풀 색상 선택창 사용 유무 지정(True : 사용 / False : 미사용)
        dlg.GetColourData().SetChooseFull(False)
        # 색상 다이얼로그에서 색상을 선택후 ok 버튼을 누르면
        if dlg.ShowModal() == wx.ID_OK:
            # 선택한 색상값을 얻엄
            data = dlg.GetColourData()
            # 선택한 색상 값을 Frame의 상태바에 출력함
            self.SetStatusText('You selected: %s\n' % str(data.GetColour().Get()))
       # 색상 다이얼로그 파괴
        dlg.Destroy()


   # 파일 오픈 다이얼로그 띄우기(이벤트 처리기)
    def openfile(self, event):
        # 파일 오픈 다이얼로그 생성
        dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "*.*", wx.OPEN)
       # 파일 다이얼로그에서 파일을 선택후 ok 버튼을 누르면
        if dlg.ShowModal() == wx.ID_OK:
                # 파일의 경로를 구함
                path = dlg.GetPath()
                # 파일 경로에서 파일명만 추출함
                mypath = os.path.basename(path)
               # 선택한 파일의 이름을 Frame의 상태바에 출력함
                self.SetStatusText("You selected: %s" % mypath)
       # 파일 오픈 다이얼로그 파괴
        dlg.Destroy()


    # 페이지 설정 다이얼로그 띄우기(이벤트 처리기)    
    def pagesetup(self, event):
        # 페이지 설정 다이얼로그 생성
        dlg = wx.PageSetupDialog(self)
       # 페이지  다이얼로그에서 페이지 설정 후 ok 버튼을 누르면        
        if dlg.ShowModal() == wx.ID_OK:
           # 페이지 설정 데이타 클래스 구함
            data = dlg.GetPageSetupData()
            # (상단, 왼쪽) 여백을 구함
            tl = data.GetMarginTopLeft()
            # (하단, 오른쪽) 여백을 구함
            br = data.GetMarginBottomRight()
            # 설정한 페이지 설정값을 Frame의 상태바에 출력함
            self.SetStatusText('Margins are: %s %s' % (str(tl), str(br)))
        # 페이지 설정 다이얼로그 파괴
        dlg.Destroy()


   # 폰트 선택 다이얼로그 띄우기(이벤트 처리기)
    def choosefont(self, event):
        # 기본 폰트 생성
        default_font = wx.Font(10, wx.SWISS , wx.NORMAL, wx.NORMAL, False, "Verdana")
        # 폰트정보 클래스 생성
        data = wx.FontData()
        # 시스템의 플랫폼이 Win32라면
        if sys.platform == 'win32':
            #폰트 이펙트 표시함.(False : 표시하지 않음)
            data.EnableEffects(True)
       # 심볼 폰트 선택 할수 없음
        data.SetAllowSymbols(False)
       # 기본 폰트로 초기화함
        data.SetInitialFont(default_font)
       # 폰트 크기 지정 범위
        data.SetRange(10, 30)
       # 폰트 다이얼로그 생성
        dlg = wx.FontDialog(self, data)
       # 폰트  다이얼로그에서 폰트 설정 후 ok 버튼을 누르면
        if dlg.ShowModal() == wx.ID_OK:
           # 설정한 폰트 정보를 얻음
            data = dlg.GetFontData()
            # 설정한 폰트를 구함
            font = data.GetChosenFont()
            # 설정한 폰트 색상을 구함
            color = data.GetColour()
           # 설정한 페이지 설정값을 Frame의 상태바에 출력함
            text = 'Face: %s, Size: %d, Color: %s' % (font.GetFaceName(), font.GetPointSize(),  color.Get())
            self.SetStatusText(text)
       # 폰트 다이얼로그 파괴            
        dlg.Destroy()

   # 디렉토리 다이얼로그 띄우기    

    def opendir(self, event):
        # 디렉토리 다이얼로그 생성
        dlg = wx.DirDialog(self, "Choose a directory:", style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)
       # 디렉토리   다이얼로그에서 디렉토리 선택 후 ok 버튼을 누르면 
        if dlg.ShowModal() == wx.ID_OK:
           # 선택한 디렉토리의 경로를 Frame의 상태바에 출력함
            self.SetStatusText('You selected: %s\n' % dlg.GetPath())
        # 디렉토리 다이얼로그 파괴
        dlg.Destroy()

   # 선택 다이얼로그 띄우기

    def singlechoice(self, event):
        # 리스트
        sins = ['Greed', 'Lust', 'Gluttony', 'Pride', 'Sloth', 'Envy', 'Wrath']
       # 선택 다이얼로그 띄우기
        dlg = wx.SingleChoiceDialog(self, 'Seven deadly sins', 'Which one?', sins, wx.CHOICEDLG_STYLE)
       # 선택   다이얼로그에서 항목 하나를  선택 후 ok 버튼을 누르면
        if dlg.ShowModal() == wx.ID_OK:
           # 선택한 항목을 Frame의 상태바에 출력함            
            self.SetStatusText('You chose: %s\n' % dlg.GetStringSelection())
        # 선택5 다이얼로그 파괴
        dlg.Destroy()

   # 텍스트 입력 다이얼로그 띄우기

    def textentry(self, event):
       # 텍스트 다이얼로그 생성
        dlg = wx.TextEntryDialog(self, 'Enter some text','Text Entry')
        # "Default" 글자를 텍스트 상자에 입력함.
        dlg.SetValue("Default")
        # 텍스트 입력  다이얼로그에서 항목 하나를  선택 후 ok 버튼을 누르면
        if dlg.ShowModal() == wx.ID_OK:
            # 입력한 항목을 Frame의 상태바에 출력함
            self.SetStatusText('You entered: %s\n' % dlg.GetValue())
       # 텍스트 입력 다이얼로그 파괴
        dlg.Destroy()

class MyApp(wx.App):
    def OnInit(self):
        myframe = MyFrame(None, -1, "commondialogs.py")
        myframe.CenterOnScreen()
        myframe.Show(True)
        return True



[실행 화면]

<<메인 윈도우>>




<< 메시지 다이얼로그 (wx.MessageDialog ) >>



<< 색상 다이얼로그 (wx.ColourDialog ) >>




<< 파일 다이얼로그 (wx.FileDialog ) >>



<< 페이지 다이얼로그 (wx.PageSetupDialog ) >>




<< 폰트 다이얼로그 (wx.FontDialog ) >>




<< 디렉토리 다이얼로그 (wx.DirDialog ) >>




<< 선택 다이얼로그 (wx.SingleChoiceDialog ) >>








블로그 이미지

slays

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

댓글을 달아 주세요

윈도우에서 UAC 설정이 되어 있을 때, 권한 상승을 요청하기 위한 코드를 stackoverflow.com 사이트에서 발견...

까먹을 수 있으니 기록~~







[그림. 1] 권한 상승 요청 화면


사이트에서 발견한 코드는 아래와 같다.


import os
import sys
import win32com.shell.shell as shell
ASADMIN = 'asadmin'

if sys.argv[-1] != ASADMIN:
    script = os.path.abspath(sys.argv[0])
    params = ' '.join([script] + sys.argv[1:] + [ASADMIN])
    shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters=params)
    sys.exit(0)


근데 저 코드를 윈도우 모드의 스크립트는 상관 없겠지만 콘솔모드의  스크립트에서 그대로 이용했을 때 관리자 권한으로 실행하지 않았을 경우, Traceback 에러 메시지를 콘솔에 뿌려버리니, 그 메시지가 좀 지저분해? 보여서 권한 상승 코드 자체를 함수화 시켜 try / except를 이용하여 오류 메시지를 안 뜨게 해버림.


어차피 권한 상승 안 시킬 때 나오는 오류는 보기 좋게 error message 를 별도 작성해서 깔끔하게 출력시키는 게 더 나을 듯 하다.


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


def uac_require(): # 관리자 권한 상승 요청 함수
asadmin = 'asadmin'
try:
if sys.argv[-1] != asadmin:
script = os.path.abspath(sys.argv[0])
params = ' '.join([script] + sys.argv[1:] + [asadmin])
shell.ShellExecuteEx(lpVerb='runas', lpFile=sys.executable, lpParameters=params)
            sys.exit()
return True

except:

return False


if __name__ == '__main__':
import win32com.shell.shell as shell
import os, sys

if uac_require(): # 관리자 권한 요청 함수 실행
print "continue" # 권한 상승 시 True 를 리턴받아서 다음 작업 수행
else: # 관리자 권한으로 실행안되면 False 받아 else 문 수행
print "error message" # else문에 별도의 메시지를 넣거나 종료 등을 수행


이런 유형으로 하니깐 개인적으로 좀 더 그냥 보기 좋아진 듯?? 흠!~~



-- [글 수정] --


실수로 위의 원본코드를 수정한 코드에 반영할 때 코드 하나를 적지 못했었다.

바로 sys.exit() 명령어인데.. 저것을 적는 이유를 간략히 설명하자면 저 코드는 A라는 프로세스가 ShellexecuteEx 메소드를 이용하여 자기 자신을 admin 권한으로 실행시키려는 행위이다.

즉, 자기 자신을 자식 프로세스로서 하나 더 띄우는 건데, 그 자식 프로세스는 if sys.argv[-1] != asadmin:이 부분의 코드를 타지 않고 흐르게 된다.

(자식은 asadmin 권한 요청으로 호출되었기 때문에 -1번째 argument에는 asadmin 이 들어가 있기 때문이다.)


다시 앞서 돌아가 sys.exit()가 필요했던 이유는 부모 프로세스 A는 자식 프로세스A를 호출하고 종료가 돼야 하기 때문이다. 근데 막상 실행하면 자식 프로세스가 종료되기 전까지 A프로세는 sys.exit()이후로 아무 작업도 안 하고 그냥 대기를 타더군.

(적은 양의 시스템 메모리 공간을 차지하게 됨.)


참고로 위의 설명은 exe로 만들어진 파일을 실행할 때에 대한 argument를 고려한 코드이다. 만약 pycharm 에서 저 코드를 실행해 버리면 argument 의 상태가 좀 달라지기 때문에 설명한 것과 약간 다르게 동작하는 경우가 발생할 수도 있다.

블로그 이미지

slays

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

댓글을 달아 주세요

기존에 Python 2.7 x86 버전과 py2exe x86 버전으로 exe로의 빌드를 했었는데, 이번에 윈도우의 x64쪽의 시스템 폴더에 접근 할 일이 생겨서 이래저래 알아보다가 윈도우의 redirection 앞에 gg를 치고 결국 x64 파이썬을 사용하기로 맘을 먹은 일이 이번에 결정...


코드상으로 x86이 x64쪽 경로를 건드리는 방법이 존재하지 않을까?란 생각을 하다가 결국 x64방식을 사용하는 쪽으로 선회..

x86 기반으로 만들어진 코드에서 x64 쪽 시스템에 접근하는 방법이 존재하려나? -_- 그런 게 있는지는 모르겠다.

(상상은 할 수 있는 요소이니 테클하는 사람들이 없었음 싶다. -_-)


그러나 아직까지는 x86을 버릴 순 없고, 아예 둘 다 같이 설치해서 쓸 수는 없을까? 라고 고민하다가 삽질을 좀 많이 한 결과 알아낸 것이, 둘이 설치 폴더를 다르게 해주면 사용이 가능해진다는 단순한 논리에 봉착.. 

(솔직히 파이썬만이 문제가 아니고, 부수적으로 설치하는 플러그인들 때문에 머리가 좀 아팠음..)


파이썬의 경우 x86이나 x64 설치 본 둘다 설치 폴더는 항상 C:\Python27 로 지정이 된다.

이것을 겹치게하면 안 되니 x86과 x64 폴더로 나누어서 설치를 해주었다.

(이렇게 해도 되는지에 대한 파이썬의 구동 메카니즘 적 확신은 없었으므로 우선 저질러 보고 테스트 해본다.)






[그림. 1] 파이썬 x86/x64 설치 폴더 분류


보통 파이썬을 설치하는 경우 윈도우의 환경 변수에 그 경로들을 지정해줘야 하는 건 사용자들이라면 기본을 알 것이고...

그 경로는 다음과 같다.


- C:\Python27\

- C:\Python27\Scripts


이 부분을 위 [그림. 1] 과 같이 파이썬을 각각 설치했다면 환경 변수는 두 버전 모두 다 추가시켜줘야 했다.


즉, 아래와 같이 추가가 될 것이다.


- C:\Python27\x86

- C:\Python27\x86\Scripts

- C:\Python27\x64

- C:\Python27\x64\Scripts


이렇게 하면 기본적인 설치는 끝이난다. 코딩은 Pycharm을 이용하기 때문에 필요에 따라 설정에서 인터프리터를 선택해서 써주면 문제될 것 없이 여기서 끝내도 될 터...


하지만 커맨드 창을 이용할 경우에는 얘기가 달라진다. 그리고 또한 플러그인들 때문에라도 말이지...


두 폴더는 전부 python.exe 와 pythonw.exe 파일을 동일하게 가지고 있다.

커맨드에서 실행을 할 경우 이름이 겹치니깐 패스 설정이 우선인 녀석의 것만 실행이 되겠지!

난 개인적으로 x64 쪽의 두 파일명을 변경시켜주기로 했다. (유저 맘대로 변경...)


python64.exe, pythonw64.exe로 이름을 바꾸고 사용하니 개인적으로 편했다. 여기 까지는 좋은데,

문제는 플러그인들...


py2exe(파이썬 파일을 exe로 빌드해주는 녀석..)이 64bit 쪽 파일의 빌드를 하지를 못하는 버그가 있었고, 아무리 검색해도 해결법을 제시한 글은 보지를 못했다.


결론은, Pyinstaller 라는 툴을 이용하라는 것이었는데, 그 플러그인은 GUI 셋업 방식이 아닌, 커맨드 설치 방식이더라.

각각의 파이썬 폴더에 설치를 해줘야 하기 때문에 두 개의 인터프리터를 모두 이용해서 설치를 해주면 각각의 라이브러리 폴더에 설치가 된다. Pyinstaller 설치할 때의 방법은 아래와 같다.

(이 녀석은 x86 / x64 설치본이 따로 존재하지 않고 하나로 다 지원이 된다. 하지만 설치는 분명 나눠서 두번 해줘야 한다.)


ex) python.exe setup.py install        # x86 쪽 설치할 때..

ex) python64.exe setup.py install     # x64 쪽 설치할 때...


Pyinstaller는 커맨드 창에서 명령어를 입력하여 파일을 빌드시켜주는게 기본이라 나도 걍 그렇게 쓰고 있는데...

(저 녀석을 이용한 좀 더 손쉽게 빌드할 수 있는 툴을 만들 수도 있겠다만... 귀찮으므로 pass)


그러나 저 플러그인은 이름이 동일하게 양쪽에 설치가 된 것이므로 x86과 x64 빌드시의 실행명 역시 나눠줄 필요가 있다.

단순히 똑같이 파일명을 변경시켜주면 아주 잘 되더라.


- C:\Python27\x64\Scripts


위 경로의 보면 pyinstaller.exe, pyinstaller-script.py 파일이 있는데 이 것들을 단순하게 변경을 시켜주었다.


- pyinstaller.exe -> pyinstaller64.exe

- pyinstaller-script.py -> pyinstaller64-script.py


두 개의 파일명이 위의 규칙처럼만 변경해주면 동작되는데 아무 문제가 없었다.

파일명 변경이 거시기 하다면 빌드하는 방법을 배치파일로 만들어서 Full path까지 기입하여 사용해도 되겠지만 뭐 암튼 그냥 잘 되는 거 확인했으니 pass


pyinstaller를 이용하면 빌드하려는 파일이 32비트 파일이 될 것이고 pyinstaller64를 이용하면 64비트로 파일을 빌드해줄 것이다.

다른 플러그인의 경우도 커맨드 방식의 설치 본일 경우는 x86과 x64가 나뉜다면 위의 유형처럼만 조금 손봐서 이용하면 무난하게 이용 가능하지 않을까 싶다.


GUI 방식으로 설치를 하던, 콘솔 방식으로 설치를 하고 사용을 할 때 겹치지 않게 한다라는 점이 중요하겠다.

블로그 이미지

slays

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

댓글을 달아 주세요