2013-09-03 2 views
2

저는 python과 wxpython을 사용하여 웹 사이트에서 파일을 다운로드하는 작은 도구를 작성하고 있습니다. 나는 모든 것을 작동 시켰고, 유일한 점은 진행률 표시 줄을 사용하여 완료를 표시하고, urlretrieve 후에 유일한 것은 진행 막대이며 GUI는 응답하지 않게된다는 것입니다. 나는 이것이 스레딩과 관련이 있다는 것을 알고 있지만, 저는 이것에 정말로 새로운 것입니다. 누군가 나에게 힌트를 줄 수 있니?wx.Gauge를 업데이트하고 현재 프레임을 활성 상태로 유지 하시겠습니까?

아이디어가 메인 프레임에 있습니다. 사이트에서 검색 결과를 가져온 결과를이 DownloadListingFrame에 제공하면 버튼과 staticText가 즉시 생성됩니다. 문제는 파일을 다운로드하면서 다운로드 버튼을 클릭 한 다음 진행률 표시 줄을 업데이트 한 것이지만 전체 앱이 중지되는 것 이외의 문제입니다. 다른 예제에서 다른 사람의 코드를 읽은 후에는 doDownload 함수를 스레드에 넣고 실행 한 것으로 생각합니다. 스레딩을 사용하지 않는 것과 같은 기능을합니다 ...

고마워요.

클래스 DownloadListingFrame (wx.Frame) :

data = '' 

def __init__(self, parent, result): 
    wx.Frame.__init__ (self, parent, id = wx.ID_ANY, title = u'result', pos = wx.DefaultPosition, size = wx.Size(500,300), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL) 
    self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) 

    self.statusbar = self.CreateStatusBar() 
    self.statusbar.SetFieldsCount(3) 

    self.progessBar = wx.Gauge(self.statusbar, -1, style=wx.GA_HORIZONTAL|wx.GA_SMOOTH) 
    rect = self.statusbar.GetFieldRect(1) 
    self.progessBar.SetPosition((rect.x+2, rect.y+2)) 
    self.progessBar.SetSize((rect.width, rect.height-4)) 

    buttonPos = 20 
    for item in result: 
     label = wx.StaticText(self, wx.ID_ANY, item, wx.Point(120 ,buttonPos+2), wx.DefaultSize, 0) 
     button = wx.Button(self, id=-1,label=u'Download', pos=(20, buttonPos)) 
     buttonPos = buttonPos + 30 
     self.Bind(wx.EVT_BUTTON, lambda x: self.Downloader(item, result[item]), button) 

    self.Centre(wx.BOTH) 


def progressUpdate(self, blockCount, blockSize, totalSize): 
    progressSoFar = int((float(blockCount) * float(blockSize)/float(totalSize)) * 100) 
    self.progessBar.SetValue(progressSoFar) 

def doDownloade(self, realAddress, saveAsFilename): 
    urllib.urlretrieve(realAddress, saveAsFilename, self.progressUpdate) 

def Downloader(self, title, url): 
    saveAsPath = wx.DirDialog(self, u"save to...") 
    if saveAsPath.ShowModal() == wx.ID_OK: 
     realAddress = self.getRealAddress(url) 
     saveAsFilename = os.path.join(saveAsPath.GetPath(), title + os.path.splitext(realAddress)[1]) 
     thread = threading.Thread(target=self.doDownloade(realAddress, saveAsFilename)) 
     thread.setDaemon(True) 
     thread.start() 

def getRealAddress(self, url): 
    import httplib 
    siteUrl = 'www.yyets.com' 
    httpConnection = httplib.HTTPConnection(siteUrl) 
    httpConnection.request("GET", url) 
    resp = httpConnection.getresponse() 
    realAddress = resp.getheaders()[6][1] 
    return realAddress 

def __del__(self): 
    pass 

답변

1

당신은 명령을 실행하는 경우 :

thread = threading.Thread(target=self.doDownloade(realAddress, saveAsFilename)) 

처음 self.doDownloade(realAddress, saveAsFilename)를 실행 한 다음이의 반환 값 (None 될 것입니다) 통과를 목표로.

대신 당신이 원하는 :

thread = threading.Thread(target=self.doDownloade, args=(realAddress, saveAsFilename)) 

주, 여기에, 나는 기능self.doDownloade에 통과 한 후 threadthread.start를 호출 할 때 당신이 그것을 준 agrs 이것을 호출합니다.

그런데 wx.Timer으로이 작업을 수행 할 수도 있습니다. 나는 게이지가 더 쉽기 때문에 게이지가 더 자주 사용되는 것을 발견하고 게이지가 업데이트되는 빈도와 게이지에 사용되는 리소스의 양을 제어 할 수 있습니다. 주요 wxPython 데모의 게이지 예제는 wx.Timer를 사용하여 좋은 출발점을 원합니다.

+0

감사합니다. –

+0

좋아요. 또한 wx.Timer를 사용할 때 마지막에 내 새로운 메모를 참조하십시오. – tom10

관련 문제