2016-12-19 2 views
0

Я пытаюсь написать приложение в wxPython, чтобы отобразить несколько элементов из магазина Amazon (на данный момент только обложки для книг в виде JPG). Я использую urllib2 и отображаю их на растровой кнопке и перечисляя их для дальнейших действий, но после ее кодирования основное окно/приложение, похоже, загружается после того, как все URL/изображения были извлечены. Googling. Я понимаю, что мы должны используйте Threads, чтобы разбить операцию во время запуска основного кода приложения, но это моя первая попытка с wxpython, и все примеры, которые я прочитал, путают меня еще больше.wxPython fetch remote image and threading

Я упомянула ниже код, с которым я работаю, для любых экспертов, которые могут дать мне представление о том, как обеспечить, чтобы каждый URL был выбран и отображен, когда он их читает ... приведенный ниже код представляет собой объединение различных примеров, найденных здесь и полотно, так пожалуйста, простите мое отсутствие навыков ..

import wx 
import os 
import sys 
import urllib2 
import cStringIO 

urls = ['https://images-na.ssl-images-amazon.com/images/I/51-u3J3mtTL._AC_US100_.jpg', 
     'https://images-na.ssl-images-amazon.com/images/I/51cRqX8DTgL._AC_US100_.jpg', 
     'https://images-na.ssl-images-amazon.com/images/I/515iBchIIzL._AC_US100_.jpg', 
     'https://images-na.ssl-images-amazon.com/images/I/511MaP7GeJL._AC_US100_.jpg', 
     'https://images-na.ssl-images-amazon.com/images/I/51jizRmRYYL._AC_US160_.jpg'] 

class Example(wx.Frame): 

    def __init__(self, *args, **kwargs): 
     super(Example, self).__init__(*args, **kwargs) 
     self.InitUI() 
     self.Ctrls() 
     self.makeButtons() 

    def makeButtons(self): 

     i = 0 

     for url in urls: 

      f = urllib2.urlopen(url) 
      data = f.read() 

      i += 1 
      print " url = ",url, " ",i 
      stream = cStringIO.StringIO(data) 
      bmp = wx.BitmapFromImage(wx.ImageFromStream(stream)) 
      button = wx.Button(self.panel, -1, "Book cover", style=wx.ALIGN_CENTER, size=wx.Size(100,100)) 
      button.SetToolTipString("wx.Button can how have an icon on the left, right,\n" 
          "above or below the label.") 
      button.SetBitmap(bmp, 
        wx.LEFT # Left is the default, the image can be on the other sides too 
        #wx.RIGHT 
        #wx.TOP 
        #wx.BOTTOM 
        ) 
      button.SetBitmapMargins((4,4)) 
      button.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD, False)) 
      self.wrapSizer.Add(button, 1, wx.EXPAND) 
     self.Show(True) 
     self.panel.Layout() 

    def InitUI(self): 
     self.SetSize((800, 400)) 
     self.SetTitle('Dynamically Flow Buttons to Next Row on Window-Resize') 
     self.Centre() 


    def Sizers(self): 
     self.wrapSizer = wx.WrapSizer() 
     self.panel.SetSizer(self.wrapSizer) 

    def Ctrls(self): 
     self.panel = wx.Panel(parent=self,pos=wx.Point(0,0), size=wx.Size(750,550), style=wx.TAB_TRAVERSAL) 
     self.Sizers() 

def main(): 

    ex = wx.App() 
    Example(None) 
    ex.MainLoop() 

if __name__ == '__main__': 
    main() 

ответ

2

Вы должны использовать темы для URL-адреса выборки, а затем использовать wx.CallAfter, чтобы вернуться к главному потоку, чтобы отобразить данные ... вот как ваш код может быть изменен

import threading 

def makeButtons(self): 


    def _update_data(data): 

     stream = cStringIO.StringIO(data) 
     bmp = wx.BitmapFromImage(wx.ImageFromStream(stream)) 
     button = wx.Button(self.panel, -1, "Book cover", style=wx.ALIGN_CENTER, size=wx.Size(100,100)) 
     button.SetToolTipString("wx.Button can how have an icon on the left, right,\n" 
         "above or below the label.") 
     button.SetBitmap(bmp, 
       wx.LEFT # Left is the default, the image can be on the other sides too 
       #wx.RIGHT 
       #wx.TOP 
       #wx.BOTTOM 
       ) 
     button.SetBitmapMargins((4,4)) 
     button.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD, False)) 
     self.wrapSizer.Add(button, 1, wx.EXPAND) 
     self.Show(True) 
     self.panel.Layout() 

    def f(): 
     f = urllib2.urlopen(url) 
     data = f.read() 
     wx.CallAfter(_update_data, data) 

    for url in urls: 
     threading.Thread(target=f).start() 
+1

Большое спасибо, я понимаю, что звонок немного бит лучше сейчас, надеюсь, это тоже помогает другим! –

+0

У меня был следующий вопрос к решению выше, для которого я открыл еще один вопрос в следующем сообщении: http://stackoverflow.com/questions/41339294/wxpython-threading-display-images-as-they-are-loaded –