问题描述
我正在尝试删除放置在面板上某个随机点的图像.此解决方案有效,但取决于我使用的配色方案.有更好的方法吗?
I am trying to remove an image that has been placed at some random point on a panel. This solution works but it is dependent upon the colour scheme that I am using. Is there a better way of doing this?
import wx
from PIL import Image
import random
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Remove image")
panel = MainPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(panel)
self.SetSizerAndFit(sizer)
self.Centre()
self.Show()
class MainPanel(wx.Panel):
"""Create a panel class to contain screen widgets."""
def __init__(self, frame):
wx.Panel.__init__(self, frame)
self.Bind(wx.EVT_PAINT, self._on_paint)
cmd_refresh = wx.Button(self, wx.ID_REFRESH)
cmd_refresh.Bind(wx.EVT_BUTTON, self._on_cmd_refresh_click)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add((500, 300))
sizer.Add(cmd_refresh, flag=wx.ALL|wx.ALIGN_CENTER, border=10)
self.SetSizer(sizer)
self.x_pos = random.randint(0, 100)
self.y_pos = random.randint(0, 100)
def _on_paint(self, event):
bitmap = self._get_image()
self._draw_image(bitmap)
def _get_image(self):
bitmap = wx.Bitmap()
bitmap.LoadFile("red.png", wx.BITMAP_TYPE_ANY)
self.image_width = bitmap.GetWidth()
self.image_height = bitmap.GetHeight()
return bitmap
def _draw_image(self, bitmap):
dc = wx.ClientDC(self)
dc.DrawBitmap(bitmap, self.x_pos, self.y_pos, True)
def _on_cmd_refresh_click(self, event):
del event
colour = (212, 212, 212)
blank_image = Image.new('RGB', (self.image_width, self.image_height), colour)
bitmap = wx.Bitmap.FromBuffer(self.image_width, self.image_height, blank_image.tobytes())
self._draw_image(bitmap)
if __name__ == '__main__':
screen_app = wx.App()
main_frame = MainFrame()
screen_app.MainLoop()
推荐答案
您只需要Refresh
您的Panel
而不重绘位图.您将在图片的位置获得Panel
背景样式.这将适用于您当前的代码(固定大小Panel
),但不适用于可以重新调整大小的Frame
,因为这会生成和生成EVT_PAINT
,并且您将再次绘制位图.为了解决这个问题,您可以使用标志来告知何时需要不带位图的Refresh
.
You only need to Refresh
your Panel
without redrawing the bitmap. You will get your Panel
background style in the place of the picture. This would work for your current code (fixed-size Panel
) but not for a Frame
that could be resized because this would produce and EVT_PAINT
and you will have again your bitmap drawn. To solve this, you can use a flag to tell when you want a Refresh
without bitmap.
代码示例可能是:
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Remove image")
panel = MainPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(panel, 1, wx.EXPAND) # I made the panel expandable sizable
self.SetSizerAndFit(sizer)
self.Centre()
self.Show()
class MainPanel(wx.Panel):
"""Create a panel class to contain screen widgets."""
def __init__(self, frame):
wx.Panel.__init__(self, frame)
self.Bind(wx.EVT_PAINT, self._on_paint)
cmd_refresh = wx.Button(self, wx.ID_REFRESH)
cmd_refresh.Bind(wx.EVT_BUTTON, self._on_cmd_refresh_click)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add((500, 300))
sizer.Add(cmd_refresh, flag=wx.ALL|wx.ALIGN_CENTER, border=10)
self.SetSizer(sizer)
self.x_pos = random.randint(0, 100)
self.y_pos = random.randint(0, 100)
self.refresh = False # flag to control drawing of bitmap
def _on_paint(self, event):
if self.refresh: return # for a clean background, return
bitmap = self._get_image()
self._draw_image(bitmap)
def _get_image(self):
bitmap = wx.Bitmap()
bitmap.LoadFile("mypng.PNG", wx.BITMAP_TYPE_ANY)
return bitmap
def _draw_image(self, bitmap):
dc = wx.ClientDC(self)
dc.DrawBitmap(bitmap, self.x_pos, self.y_pos, True)
def _on_cmd_refresh_click(self, event):
self.refresh = True # forget the bitmap
self.Refresh() # and refresh the screen
另一种选择是创建大小为0的Bitmap
来替换原始的.请注意,为此,您必须将_on_paint
调用与位图的读取解耦.否则,每次调整窗口大小时,您都会重新阅读原始图片:
Another option is to create a Bitmap
of size 0 to replace the original one. Note that for this you have to decouple the _on_paint
call from the reading of the bitmap. Otherwise you will re-read the original picture each time you resize your window:
class MainPanel(wx.Panel):
"""Create a panel class to contain screen widgets."""
def __init__(self, frame):
wx.Panel.__init__(self, frame)
self.Bind(wx.EVT_PAINT, self._on_paint)
cmd_refresh = wx.Button(self, wx.ID_REFRESH)
cmd_refresh.Bind(wx.EVT_BUTTON, self._on_cmd_refresh_click)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add((500, 300))
sizer.Add(cmd_refresh, flag=wx.ALL|wx.ALIGN_CENTER, border=10)
self.SetSizer(sizer)
self.x_pos = random.randint(0, 100)
self.y_pos = random.randint(0, 100)
self._get_image()
def _on_paint(self, event):
self._draw_image()
def _get_image(self):
self.bitmap = wx.Bitmap()
self.bitmap.LoadFile("mypng.PNG", wx.BITMAP_TYPE_ANY)
def _draw_image(self):
dc = wx.ClientDC(self)
dc.DrawBitmap(self.bitmap, self.x_pos, self.y_pos, True)
def _on_cmd_refresh_click(self, event):
self.bitmap = wx.Bitmap(0,0)
self._draw_image()
self.Refresh()
这篇关于如何在wxPython中删除图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!