我正在编写一个GUI来从定义的URL列表中显示一些图像(亚马逊的书籍封面),我已经能够成功地将它们加载到面板中,但是尽管使用了线程,GUI似乎要等到所有的循环结束,然后所有的图像同时出现,我如何才能实现GUI来显示每个图像,因为它们是运行的,time..the图形界面基本上是冻结的,直到图像是fetched...Thanks!
问题再次是要确保我可以在图形用户界面上显示每一张图片,因为它们是被拉出来的,而不是同时显示的.
import wx
import os
import sys
import urllib2
import cStringIO
import threading
import time
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',
'https://images-na.ssl-images-amazon.com/images/I/51jizRmRYYL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/31Pw7voGDFL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/51g30m1xpPL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/51qx+6aQUnL._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):
def _update_data(data):
time.sleep(2)
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()
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()发布于 2016-12-27 23:47:37
还可以一次分离所有线程,就像在问题中的代码示例中尝试过的那样。原始代码中的问题是,由于处理位图请求的时间延迟,GUI处于阻塞状态。
请记住,在下面的示例中,位图的顺序将取决于线程正在完成的顺序(在本例中是随机的)。
import wx
import urllib2
import cStringIO
import threading
import time
from random import random
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',
'https://images-na.ssl-images-amazon.com/images/I/51jizRmRYYL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/31Pw7voGDFL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/51g30m1xpPL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/51qx+6aQUnL._AC_US160_.jpg']
def url2bmp(url, callback):
f = urllib2.urlopen(url)
data = f.read()
# to simulate random read delay
time.sleep(2 * random())
stream = cStringIO.StringIO(data)
bmp = wx.BitmapFromImage(wx.ImageFromStream(stream))
wx.CallAfter(callback, bmp)
class Example(wx.Frame):
def __init__(self, *args, **kwargs):
super(Example, self).__init__(*args, **kwargs)
self.InitUI()
self.Ctrls()
self.Show(True)
self.makeButtons()
def makeButtons(self):
for url in urls:
threading.Thread(target=url2bmp, args=(url, self.update_ui)).start()
def update_ui(self, bmp):
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
)
self.wrapSizer.Add(button, 1, wx.EXPAND)
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()编辑:重写示例,首先生成空按钮,然后在它们到达时立即应用位图。这现在更丑了,现在应该重构一个比使用标签(Mis)更安全的到url的映射按钮。
import wx
import urllib2
import cStringIO
import threading
import time
from random import random
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',
'https://images-na.ssl-images-amazon.com/images/I/51jizRmRYYL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/31Pw7voGDFL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/51g30m1xpPL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/51qx+6aQUnL._AC_US160_.jpg']
def url2bmp(url, callback):
f = urllib2.urlopen(url)
data = f.read()
# to simulate random read delay
time.sleep(2 * random())
stream = cStringIO.StringIO(data)
bmp = wx.BitmapFromImage(wx.ImageFromStream(stream))
wx.CallAfter(callback, url, bmp)
class Example(wx.Frame):
def __init__(self, *args, **kwargs):
super(Example, self).__init__(*args, **kwargs)
self.InitUI()
self.Ctrls()
self.Show(True)
self.makeButtons()
def makeButtons(self):
for url in urls:
self.update_ui(url)
threading.Thread(target=url2bmp, args=(url, self.update_ui)).start()
def update_ui(self, url, bmp=None):
if bmp is None:
# create button, but not bitmap
button = wx.Button(self.panel, -1, url, 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.")
self.wrapSizer.Add(button, 1, wx.EXPAND)
else:
children = self.wrapSizer.GetChildren()
# http://www.blog.pythonlibrary.org/2012/08/24/wxpython-how-to-get-children-widgets-from-a-sizer/
for widget in children:
button = widget.GetWindow()
if isinstance(button, wx.Button):
if button.GetLabel() == url:
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.SetLabel('')
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()发布于 2016-12-27 12:11:44
允许自己重写。重要的是尽快退出__init__方法(在启动线程之前调用Show )并让线程异步工作。您还同时启动了所有线程,而这个示例使用一个线程获取一个又一个位图。
import wx
import os
import sys
import urllib2
import cStringIO
import threading
import time
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',
'https://images-na.ssl-images-amazon.com/images/I/51jizRmRYYL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/31Pw7voGDFL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/51g30m1xpPL._AC_US160_.jpg',
'https://images-na.ssl-images-amazon.com/images/I/51qx+6aQUnL._AC_US160_.jpg']
def gen_urls():
"""Gives back one bitmap after another."""
for url in urls:
f = urllib2.urlopen(url)
data = f.read()
time.sleep(2)
stream = cStringIO.StringIO(data)
bmp = wx.BitmapFromImage( wx.ImageFromStream( stream ) )
yield bmp
class Example(wx.Frame):
def __init__(self, *args, **kwargs):
super(Example, self).__init__(*args, **kwargs)
self.InitUI()
self.Ctrls()
self.Show(True)
threading.Thread(target=self.makeButtons).start()
def makeButtons(self):
for bmp in gen_urls():
wx.CallAfter(self.update_ui, bmp)
def update_ui(self, bmp):
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.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()https://stackoverflow.com/questions/41339294
复制相似问题