python - Image is not displaying at runtime in panel, wxpython
问题描述
I am trying to display all images from image folder using for loop and that all displayed correctly. But i want to add another image at runtime so I use threading here threading.Timer(2.0, self.basicgui).start()
whenever I add new image to folder i can see the name of image in image list but it can't be updated. i want to refresh panel to show updated image how can i fix this.
import wx
import threading
from PIL import Image
import wx.lib.scrolledpanel
import os
class windowclass(wx.Frame):
def __init__(self, *args, **kwargs):
super(windowclass, self).__init__(*args, **kwargs)
global panel1
panel1 = wx.Panel(self,size=(1000,28), pos=(0,0), style=wx.SIMPLE_BORDER)
panel1.SetBackgroundColour('#FDDF99')
global panel2
panel2 = wx.lib.scrolledpanel.ScrolledPanel(panel1,-1, size=(350,710), pos=(1010,0), style=wx.SIMPLE_BORDER)
panel2.SetupScrolling()
panel2.SetBackgroundColour('#FFFFFF')
self.basicgui()
def basicgui(self):
padding = 0
bSizer = wx.BoxSizer( wx.VERTICAL )
self.jpgs = GetJpgList("./image")
allimage = len(self.jpgs)
print(allimage)
for i in range(0,allimage):
#print("i=",i)
bitmap = wx.Bitmap(self.jpgs[i])
image = wx.ImageFromBitmap(bitmap)
image = image.Scale(300, 200, wx.IMAGE_QUALITY_HIGH)
bitmap = wx.BitmapFromImage(image)
control = wx.StaticBitmap(panel2, -1, bitmap)
#print(control)
control.SetPosition((10, padding+10))
padding += 210
bSizer.Add( control, 0, wx.ALL, 5 )
panel2.SetSizer( bSizer )
panel2.Layout()
threading.Timer(2.0, self.basicgui).start()
self.Show()
return
def GetJpgList(dir):
jpgs = [f for f in os.listdir(dir) if f[-4:] == ".jpg"]
# print "JPGS are:", jpgs
return [os.path.join(dir, f) for f in jpgs]
def main():
app = wx.App()
windowclass(None)
app.MainLoop()
main()
解决方案
Here is your code, amended to be a bit more efficient.
Currently, you generate the images every time, which with a small number may be fine but if there are a lot of images this will eat your cpu.
Here, I've built a dictionary of the images, so only additions and deletions need to be transformed. It's also useful to discover if any work needs to be done at all, so I've assumed that a simple count can tell me that nothing has changed and therefore no work needs to be done.
import wx
import wx.lib.scrolledpanel
import glob
class windowclass(wx.Frame):
def __init__(self, *args, **kwargs):
super(windowclass, self).__init__(*args, **kwargs)
self.panel1 = wx.Panel(self,size=(1000,28), style=wx.SIMPLE_BORDER)
self.panel1.SetBackgroundColour('#FDDF99')
self.panel2 = wx.lib.scrolledpanel.ScrolledPanel(self.panel1,-1, size=(350,550))
self.panel2.SetupScrolling()
self.panel2.SetBackgroundColour('#FFFFFF')
self.panel2.SetMinSize((350,550))
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.basicgui, self.timer)
self.dict = {}
self.bSizer = wx.BoxSizer( wx.VERTICAL )
self.panel2.SetSizer(self.bSizer)
self.mainsizer = wx.BoxSizer( wx.HORIZONTAL )
self.mainsizer.Add(self.panel1,1,wx.EXPAND)
self.SetSizer(self.mainsizer)
self.timer.Start(2000)
def basicgui(self,event):
self.GetJpgList("./images")
allimage = len(self.dict)
items = self.bSizer.GetChildren()
#if the image count is the same as before nothing has changed - bail
if len(items) == allimage:
return
#remove existing images from the sizer
for i in items:
i.GetWindow().Destroy()
# add images to the sizer
for item, bitmap in self.dict.items():
control = wx.StaticBitmap(self.panel2, -1, bitmap)
self.bSizer.Add( control, 0, wx.CENTER|wx.ALL, 5 )
#reset scrolling
self.panel2.SetupScrolling(scrollToTop=False)
self.Layout()
self.Show()
def GetJpgList(self, dir):
#use glob rather than os.listdir
jpgs = glob.glob(dir+"/*.jpg")
#Build a dictionary of the images
#this way we only have to create them once
for i in jpgs:
#if image already in dict bail
if i in self.dict:
continue
print("adding", i)
bitmap = wx.Bitmap(i)
image = bitmap.ConvertToImage()
image = image.Scale(300, 200, wx.IMAGE_QUALITY_HIGH)
bitmap = wx.Bitmap(image)
self.dict[i] = bitmap
#make a list of any deleted images
del_list = []
for i in self.dict:
if i not in jpgs:
del_list.append(i)
#remove deleted images from the dictionary
for i in del_list:
self.dict.pop(i)
print("deleting",i)
return
def main():
app = wx.App()
windowclass(None)
app.MainLoop()
main()
推荐阅读
- docker - 已经使用 docker 限制,为什么服务器 cpu 平均负载仍然很高
- javascript - “无法对未安装的组件执行 React 状态更新”错误
- java - MySQL TestContainers init-script 模式创建失败
- mysql - 为什么在插入过程中发生重复键错误时设置共享锁
- javascript - 简单的 PurgeCSS
- c - C - 单独的链式哈希表 - 输出和空间问题
- javascript - 连续显示两个 Div 列,这样它也可以与 AMP(加速移动页面)一起使用
- ruby-on-rails - 销毁方法:为 API 收集的数据传递参数
- windows - 如何访问 Windows Batch 中变量中的各个项目?
- python - 矩形在 Pygame 中不动