如何在wxPython中删除图像

时间:2017-11-09 13:51:39

标签: wxpython-phoenix

我正在尝试删除放置在面板上某个随机点的图像。此解决方案有效,但它取决于我使用的配色方案。有没有更好的方法呢?

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()

[12月17日编辑:将wx.PaintDC改为wx.ClientDC]

1 个答案:

答案 0 :(得分:0)

您只需要Refresh Panel而无需重新绘制位图。您将在图片的位置获得Panel背景样式。这适用于您当前的代码(固定大小Panel),但不适用于可以调整大小的Frame,因为这会产生EVT_PAINT并且您将再次绘制您的位图。要解决此问题,您可以使用标志来判断何时需要Refresh而不使用位图。

代码示例可以是:

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。请注意,为此,您必须将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() 调用与位图的读取分离。否则,每次调整窗口大小时,您都会重新阅读原始图片:

{{1}}