如何在wxPython中删除图像 [英] How to remove image in wxPython

查看:156
本文介绍了如何在wxPython中删除图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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中删除图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆