wxPython JSON Pretty Viewer

Posted at 2010/11/29 20:44// Posted in wxPython/etc


import wx
import os
import simplejson as json

class TestFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title, pos=(0, 0), size=(480, 640))
self.CentreOnScreen(wx.BOTH)

textCtrl = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.TE_RICH2)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(textCtrl, 1, wx.ALL|wx.EXPAND, 0)
self.SetSizer(sizer)
self.SetAutoLayout(True)
textCtrl.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter)

self.textCtrl = textCtrl

def OnTextEnter(self, evt):
print "enter"
data = json.loads(self.textCtrl.GetValue())
text = json.dumps(data, indent=4)
text = text.replace("\\n", "")
text = text.replace('\\"', '"')
self.textCtrl.SetValue(text)

class TestApp(wx.App):
def OnInit(self):
"OnInit"
frame = TestFrame(None, "TestApp")
frame.Show()
self.SetTopWindow(frame)
return True

def OnExit(self):
"OnExit"
pass

TestApp(redirect=False).MainLoop()


Copy & Paste 후 Enter 누르면 한줄 JSON 이 이쁘게 보입니다.
이올린에 북마크하기
2010/11/29 20:44 2010/11/29 20:44
관련글:
http://python.kr/viewtopic.php?t=26568

버튼이 리스트에 들어가게 될 경우 버튼 하나 하나에 일일이 이벤트 핸들러를 붙이는 것은 무리입니다.
더군다나 실시간으로 추가되거나 삭제될 경우에는 아예 불가능하죠.


이럴때 2.2 시절에는 lambda 로 했었는데


# vi: set sw=4 sts=4 expandtab:
buttons = []

for button, index in zip(buttons, range(10)):
button.Bind(wx.EVT_BUTTON, lambda evt: self.OnClickButton(evt, index))

def OnClickButton(evt, index):
print index


요즘에는 내부가 전부 이터레이터식으로 변경되어서 안 되는 군요 (전부 마지막 값으로 ㄷㄷㄷ; )



# vi: set sw=4 sts=4 expandtab:
import wx
import copy

class TestFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, -1, title, pos=(0, 0), size=(320, 240))
self.CentreOnScreen(wx.BOTH)

vsizer = wx.BoxSizer(wx.VERTICAL)
for i in range(5):
button = wx.Button(self, -1, "test%d" % i)
button.Bind(wx.EVT_BUTTON, self.OnClickButton)
vsizer.Add(button)
self.SetSizer(vsizer)

def OnClickButton(self, evt):
print evt.GetEventObject().GetLabel() # POINT!!

class TestApp(wx.App):
def OnInit(self):
"OnInit"
frame = TestFrame(None, "TestApp")
frame.Show()
self.SetTopWindow(frame)
return True

def OnExit(self):
"OnExit"
pass

TestApp(redirect=False).MainLoop()


wxEvent::GetEventObject() 로 해결 하는 것이 가장 아름다운 것 같내요 : )
이올린에 북마크하기(0) 이올린에 추천하기(0)
2010/06/04 15:41 2010/06/04 15:41

wxPython PathTreeCtrl

Posted at 2010/05/26 13:26// Posted in wxPython/wxTreeCtrl
트리 컨트롤은 디렉토리 구조를 표현할때 편리합니다.

사용자 삽입 이미지
















그런데 경로를 파싱해서 디렉토리를 만드는건 의외로 귀찮은 일이더라구요 = =)~

그래서 만들어본 예제입니다



# vi: set sw=4 sts=4 expandtab:
import wx
import os

class wxPathTreeCtrl(wx.TreeCtrl):
def __init__(self, *args, **kwargs):
wx.TreeCtrl.__init__(self, *args, **kwargs)

def InitRoot(self, rootPath):
self.branchd = {}
self.DeleteAllItems()
self.root = self.AddRoot(rootPath)
self.SetPyData(self.root, ("ROOT", rootPath))
return self.root

def AppendPath(self, path):
branch = path

branches = []
while branch:
branch, leaf = os.path.split(branch)
if branch in self.branchd:
break
elif branch:
branches.append(branch)

branches.reverse()

last = self.branchd.get(branch, self.root)
for branch in branches:
last = self.AppendItem(last, os.path.split(branch)[1])
self.SetPyData(last, ("DIR", branch))
self.branchd[branch] = last

item = self.AppendItem(last, os.path.split(path)[1])
self.SetPyData(item, ("FILE", path))
return item

def ExpandAllDirs(self):
self.ExpandDirs(self.root)

def ExpandDirs(self, node):
if self.GetPyData(node)[0] == "FILE":
pass
else:
children = list(self.GenChildren(node))
fileCount = len([child for child in children if self.GetPyData(child)[0] == "FILE"])
if 0 == fileCount:
self.Expand(node)

for child in children:
self.ExpandDirs(child)

def GetBranchd(self):
return self.branchd

def GenChildren(self, node):
child = self.GetFirstChild(node)[0]
while child:
yield child
child = self.GetNextSibling(child)

if __name__ == "__main__":

class TestFrame(wx.Frame):
def __init__(self, parent, title, size=(800, 600)):
wx.Frame.__init__(self, parent, -1, title, pos=(0, 0), size=size)
self.CentreOnScreen(wx.BOTH)

self.pathTreeCtrl = wxPathTreeCtrl(self)
self.pathTreeCtrl.InitRoot("root")
self.pathTreeCtrl.AppendPath("bin/main.exe")
self.pathTreeCtrl.AppendPath("data/char/pc/warrior/warriror.png")
self.pathTreeCtrl.AppendPath("data/char/pc/warrior/warriror2.png")
self.pathTreeCtrl.ExpandAllDirs()

class TestApp(wx.App):
def OnInit(self):
toolFrame = TestFrame(None, "TEST")
toolFrame.Show()
self.SetTopWindow(toolFrame)
return True

TestApp(redirect=False).MainLoop()


이올린에 북마크하기(0) 이올린에 추천하기(0)
2010/05/26 13:26 2010/05/26 13:26
wxPython 은 수많은 pyd 파일을 가지고 있습니다.

파이썬의 pyd 파일은 dll 파일로
실행되는 프로그램이나 환경 변수 PATH 내에 존재해야지만 암묵적으로 로딩됩니다.
다른 파이썬 파일처럼 sys.path.append(dll위치) 같은 꼼수로는 로딩되지 않습니다.

그래서 wxPython 으로 만든 프로그램을 배포할때는 문제가 생깁니다.

이를 해결하기 위한 가장 쉬운 방법은
wxPython 을 인스톨하라고 하던가-_-
수많은 pyd 파일을 실행파일 폴더에 넣는 것입니다-_-
하지만 둘다 썩 좋은 방법은 아니죠-_-

여기서 구원의 동아줄 ~(-_-)~
py2exe 에서는 각종 파이썬 모듈들을 잘 모아서 깔끔하게 한폴더에 넣어준다는 것입니다.
이때 만들어지는 library.zip 을 쓰면 파이썬이 없어도 잘 실행이 됩니다.

어떻게 구현한걸까요?

해답은...

more..










이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/02/11 18:27 2009/02/11 18:27
원래는 리스트 컨트롤로 프로퍼티 컨트롤을 구성하려고 했습니다만;
처리해줘야 할 부분이 너무 많더군요 T_T)~

그러던중 vc2005 의 프로퍼티 컨트롤을 spy 로 찍어보니 PropertyGrid 로 나왔던지라
wxGrid 를 이용해서 PropertyGrid 를 구현해보고 있는중입니다.

import wx
import wx.grid

class PropertyGrid(wx.grid.Grid):
    def __init__(self, parent, keys = []):
        wx.grid.Grid.__init__(self, parent, -1)
        self.CreateGrid(len(keys), 2)
        self.SetColLabelSize(0)
        self.SetRowLabelSize(0)
        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.Bind(wx.grid.EVT_GRID_COL_SIZE, self.OnColSize)
        self.keyCellWidth = 100

        for row, key in enumerate(keys):
            self.SetReadOnly(row, 0)
            self.SetCellValue(row, 0, key)

    def SetCellChoice(self, row, choices, sel = 0):
        self.SetCellEditor(row, 1, wx.grid.GridCellChoiceEditor(choices))
        self.SetCellValue(row, 1, choices[sel])

    def OnColSize(self, evt):
        evt.Skip()

        self.keyCellWidth = self.GetColSize(0)

    def OnSize(self, evt):
        evt.Skip()
        w, h = evt.GetSize()

        self.SetColSize(0, self.keyCellWidth)
        self.SetColSize(1, w - self.keyCellWidth)

class TestFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title, pos=(0, 0), size=(320, 240))
        self.CentreOnScreen(wx.BOTH)

        grid = PropertyGrid(self, ["race", "body", "face", "hair"])
        grid.SetCellChoice(0, ["human_m", "human_f"])
        grid.SetCellChoice(1, ["body0", "body1", "body2", "body3", "body4"])
        grid.SetCellChoice(2, ["face0", "face1", "face2", "face3", "face4"])

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(grid, 1, wx.EXPAND|wx.ALL, 0)
        self.SetSizer(sizer)



class TestApp(wx.App):
    def OnInit(self):
        "OnInit"

        frame = TestFrame(None, "TestApp")
        frame.Show()
        self.SetTopWindow(frame)
        return True

    def OnExit(self):
        "OnExit"
        pass

TestApp(redirect=False).MainLoop()


이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/08/29 12:44 2007/08/29 12:44

wx파이썬 그리드

Posted at 2007/08/29 12:40// Posted in wxPython/wxGrid
import wx
import wx.grid

class TestFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title, pos=(0, 0), size=(320, 240))
        self.CentreOnScreen(wx.BOTH)

        grid = wx.grid.Grid(self, -1)
        grid.CreateGrid(25, 1)
        grid.SetColLabelValue(0, "value")
        grid.SetRowLabelValue(0, "race")
        grid.SetRowLabelValue(1, "body")
        grid.SetRowLabelValue(2, "face")
        grid.SetRowLabelValue(3, "hair")
        grid.SetColLabelSize(20)
        grid.SetRowLabelSize(50)
        grid.SetCellEditor(0, 0, wx.grid.GridCellChoiceEditor(["human_m", "human_f"]))
        grid.SetCellEditor(1, 0, wx.grid.GridCellChoiceEditor(["body0", "body1", "body2", "body3", "body4"]))
        grid.SetCellEditor(2, 0, wx.grid.GridCellChoiceEditor(["face0", "face1", "face2", "face3", "face4"]))


        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(grid, 1, wx.EXPAND|wx.ALL, 0)
        self.SetSizer(sizer)



class TestApp(wx.App):
    def OnInit(self):
        "OnInit"

        frame = TestFrame(None, "TestApp")
        frame.Show()
        self.SetTopWindow(frame)
        return True

    def OnExit(self):
        "OnExit"
        pass

TestApp(redirect=False).MainLoop()
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/08/29 12:40 2007/08/29 12:40
import wx

class TestFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title, pos=(0, 0), size=(320, 240))
        self.CentreOnScreen(wx.BOTH)

        testListCtrl = self.MakeTestListCtrl()

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(testListCtrl, 1, wx.EXPAND|wx.ALL, 5)
        self.SetSizer(sizer)

        self.testListCtrl = testListCtrl

    def MakeTestListCtrl(self):
        imgList = wx.ImageList(1, 20)

        testListCtrl = wx.ListCtrl(self, -1, style = wx.LC_REPORT| wx.LC_SINGLE_SEL )
        testListCtrl.SetImageList(imgList, wx.IMAGE_LIST_SMALL)
        testListCtrl.InsertColumn(0, "label")
        testListCtrl.InsertColumn(1, "info")
        testListCtrl.SetColumnWidth(0, 50)
        testListCtrl.SetColumnWidth(1, 50)


        testListCtrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTestListCtrlItemSelected)
        testListCtrl.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnTestListCtrlItemDeselected)

        index = testListCtrl.InsertStringItem(0, "item0")
        testListCtrl.SetStringItem(index, 1, "value0")
        testListCtrl.SetItemImage(index, 0)

        index = testListCtrl.InsertStringItem(0, "item1")
        testListCtrl.SetStringItem(index, 1, "value1")

        self.listCombo = wx.ComboBox(testListCtrl, -1, "test", choices = ["test", "test2", "test3"], style=wx.CB_DROPDOWN)
        self.listCombo.Hide()

        return testListCtrl

    def OnTestListCtrlItemSelected(self, evt):
        print "item(%d): selected"  % evt.GetIndex()

        print "label", self.testListCtrl.GetItemRect(evt.GetIndex(), wx.LIST_RECT_LABEL)
        print "bound", self.testListCtrl.GetItemRect(evt.GetIndex())

        x, y, w, h = self.testListCtrl.GetItemRect(evt.GetIndex())

        col0_w = self.testListCtrl.GetColumnWidth(0)
        col1_w = self.testListCtrl.GetColumnWidth(1)

        self.listCombo.Move((x + col0_w, y))
        self.listCombo.SetSize((col1_w, h))
        self.listCombo.Show()


    def OnTestListCtrlItemDeselected(self, evt):
        print "deselected"
        self.listCombo.Hide()

class TestApp(wx.App):
    def OnInit(self):
        "OnInit"

        frame = TestFrame(None, "TestApp")
        frame.Show()
        self.SetTopWindow(frame)
        return True

    def OnExit(self):
        "OnExit"
        pass

TestApp(redirect=False).MainLoop()
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/08/27 10:13 2007/08/27 10:13

wx파이썬: wx.ListCtrl

Posted at 2007/08/24 17:44// Posted in wxPython/wxListCtrl
import wx

class TestFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title, pos=(0, 0), size=(320, 240))
        self.CentreOnScreen(wx.BOTH)

    testListCtrl = wx.ListCtrl(self, -1, style = wx.LC_REPORT| wx.LC_SINGLE_SEL )
    testListCtrl.InsertColumn(0, "label")

    testListCtrl.SetColumnWidth(0, 120)
    testListCtrl.InsertStringItem(0, "item0")

    sizer = wx.BoxSizer(wx.VERTICAL)
    sizer.Add(testListCtrl, 1, wx.EXPAND|wx.ALL, 5)
    self.SetSizer(sizer)

class TestApp(wx.App):
    def OnInit(self):
        "OnInit"

        frame = TestFrame(None, "TestApp")
        frame.Show()
        self.SetTopWindow(frame)
        return True

    def OnExit(self):
        "OnExit"
        pass

TestApp(redirect=False).MainLoop()
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/08/24 17:44 2007/08/24 17:44
def OnCopy():
    value = 뭔가데이터

    if wx.TheClipboard.Open():
        do = wx.TextDataObject()
        do.SetText(value.replace(U"\n", U"\r\n"))
        wx.TheClipboard.SetData(do)
        wx.TheClipboard.Close()

def OnPaste():
    if wx.TheClipboard.Open():
        do = wx.TextDataObject()
        if wx.TheClipboard.GetData(do):
            value = do.GetText()
          
        wx.TheClipboard.Close()

클립보드를 사용한 copy & paste 코드입니다.
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/07/25 14:54 2007/07/25 14:54
wx.TextCtrl.SetSelection 으로 선택 영역을 지정해도 하이라이팅 (high lighting)이 보이지 않는 경우가 있다. 이 문제는 포커스를 맞추어 주지 않아서 발생하는 문제로

textCtrl.SetFocus()
textCtrl.SetSelection(-1, -1) # 전체 선택

위처럼 수정하면 선택 영역이 보이게 된다.
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/07/25 12:58 2007/07/25 12:58