2013-09-03 1 views
2

Я пишу небольшой инструмент, который загружает файл с веб-сайта с помощью python и wxpython. У меня все работает, единственное, что меня беспокоит, это то, что я хочу использовать индикатор выполнения, чтобы показать завершение, а после urlretrieve единственное, что движется - это прогресс, GUI просто перестает реагировать. Я знаю, что это связано с потоками, но я действительно новичок в этом. может кто-нибудь дать мне подсказку?обновление wx.Gauge и сохранить текущую рамку в живых?

Идея в основном кадре Я получаю результат поиска с сайта и даю результат этому DownloadListingFrame, затем он генерирует кнопки и staticText на лету. проблема была после нажатия кнопки загрузки, обновления progressbar при загрузке файла, но кроме того, что все приложение зависает. После прочтения чужого кода из другого примера, я подумал, что я положил функцию doDownload в поток и выполнил его, он действует так же, как не использует threading ...

Спасибо в продвинутом виде.

класс 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, а затем thread будем называть это с АГРС, которые вы дали, когда вы звоните thread.start.

Кстати, вы также можете сделать это с помощью wx.Timer. Я обычно считаю, что это лучший инструмент для датчиков, поскольку это проще, и вы можете контролировать, как часто обновляется калибровка, и, следовательно, сколько ресурсов используется для датчика. В главном примере демонстрационного примера wxPython используется wx.Timer, вы хотите хорошую отправную точку.

+0

спасибо, все получилось. –

+0

Отлично. Также см. Мою новую заметку в конце, используя wx.Timer. – tom10

Смежные вопросы