사용한 module version
- wxpython version : wxpython 2.8.12.1
- python version : python 2.7
wxpython 에 있는 pubsub와 py2exe 를 같이 사용할 때 문제점.
Publisher 를 사용하는 데에 py2exe 로 변환후에 error 가 발생했다.from wx.lib.pubsub import Publisherpy2exe 를 이용해서 exe 를 만든후에 실행을 하면, 이 부분에서 Publisher 를 찾을 수 없다는 에러가 뜬다.
결론부터 이야기 하면 kwargs 를 사용하는 pub 로 converting 했다.
from wx.lib.pubsub import setuparg1
이것은 wxpython 2.8.10.1 에서는 발생하지 않지만, 이후 버전에서 kwargs 가 추가 되고 문제가 발생한다고 한다.from wx.lib.pubsub import setuparg1를 추가 하면 된다고 해서 기존코드에 추가해서 다시 py2exe 를 해서 실행했다. 일단 Publisher 를 찾기는 하지만 args1 을 사용하는 Publisher 가 import 되지 않는다. 그래서 subscribe 을 한 listener 를 부르지 않는등의 이상한 현상이 보였다.
'pubsub.*', 'pubsub.core.*', 'pubsub.core.arg1.*'
setup.py 에서 'pubsub.*', 'pubsub.core.*', 'pubsub.core.arg1.*' 를 넣으면 된다고 해서 넣고는 py2exe 를 실행했지만, 여전히 안됐다.from distutils.core import setup import py2exe setup( windows=[{"script": "getMangaW.py"}], options={ "py2exe": { 'packages':['wx.lib.pubsub'], "includes": ["lxml.etree", "lxml._elementpath","wx.lib.pubsub.*", "wx.lib.pubsub.core.*", "wx.lib.pubsub.core.args1.*" ], "excludes":["mswsock.dll", "powrprof.dll", "uxTheme.dll", "MSVCP90.dll"], "bundle_files": 3, # the less, the more zip "optimize":2 } }, zipfile = "lib/library.zip" )
kwargs 로 변환
ref. 2 에서 pubsub 해결책에 대해 많이 논하고 있다. 일단 arg1 을 이용한 방법을 최대한 찾아보았으나, 결론적으로 실패했다.결국 arg1 을 사용하던 것은 kwargs 로 변환하였다. 그것이 차라리 간단하고 빠를 듯 하다. kwargs 의 예제는 ref. 3, ref. 4, ref. 5 을 참조하자.
Example
ref. 6 의 args1 을 사용한 source code 를 kwargs 로 변환했다.import time import wx from threading import Thread from wx.lib.pubsub import setupkwargs from wx.lib.pubsub import pub ######################################################################## class TestThread(Thread): """Test Worker Thread Class.""" #---------------------------------------------------------------------- def __init__(self): """Init Worker Thread Class.""" Thread.__init__(self) self.start() # start the thread #---------------------------------------------------------------------- def run(self): """Run Worker Thread.""" # This is the code executing in the new thread. for i in range(6): time.sleep(10) wx.CallAfter(self.postTime, i) time.sleep(5) wx.CallAfter(pub.sendMessage, "update", data = "Thread finished!") #---------------------------------------------------------------------- def postTime(self, amt): """ Send time to GUI """ amtOfTime = (amt + 1) * 10 pub.sendMessage("update", data = amtOfTime) ######################################################################## class MyForm(wx.Frame): #---------------------------------------------------------------------- def __init__(self): wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial") # Add a panel so it looks the correct on all platforms panel = wx.Panel(self, wx.ID_ANY) self.displayLbl = wx.StaticText(panel, label="Amount of time since thread started goes here") self.btn = btn = wx.Button(panel, label="Start Thread") btn.Bind(wx.EVT_BUTTON, self.onButton) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.displayLbl, 0, wx.ALL|wx.CENTER, 5) sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5) panel.SetSizer(sizer) # create a pubsub receiver pub.subscribe(self.updateDisplay, "update") #---------------------------------------------------------------------- def onButton(self, event): """ Runs the thread """ TestThread() self.displayLbl.SetLabel("Thread started!") btn = event.GetEventObject() btn.Disable() #---------------------------------------------------------------------- def updateDisplay(self, data): """ Receives data from thread and updates the display """ t = data # t = msg.data if isinstance(t, int): self.displayLbl.SetLabel("Time since thread started: %s seconds" % t) else: self.displayLbl.SetLabel("%s" % t) self.btn.Enable() #---------------------------------------------------------------------- # Run the program if __name__ == "__main__": app = wx.PySimpleApp() frame = MyForm().Show() app.MainLoop()
댓글 없음:
댓글 쓰기