2017-11-09 2 views
-1

패널의 임의의 지점에 배치 된 이미지를 제거하려고합니다. 이 솔루션은 작동하지만 사용중인 색 구성표에 따라 다릅니다. 이 작업을 수행하는 더 좋은 방법이 있습니까?wxPython에서 이미지를 제거하는 방법

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월 29일 17 : wx.ClientDC에 wx.PaintDC 변경] 당신은 비트 맵을 다시 그릴없이 PanelRefresh 필요

+0

코드가 실패 : 그렇지 않으면 당신은 원본 사진 당신의 창을 때마다 크기를 조정할 다시 읽습니다 wxPaintDCImpl :: wxPaintDCImpl()에서 .. \ .. \ src \ msw \ dcclient.cpp (277)에서 C++ 어설 션 "어설 션 오류"가 실패했습니다 : wxPaintDCImpl이 (가) wxPaintDCImpl()에서 dc = wx.PaintDC – joaquin

+0

나를 위해 일하는 파이썬 3.5.2, wxPython 4.0.0b2 gtk2 (phoenix) – Psionman

+0

우분투 16.04. 나는 윈도우에서 테스트 할 것이다 – Psionman

답변

0

. 그림 대신에 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 호출을 분리해야합니다. _draw_image에, 라인 42 : `파일 "/Python36/programas/test/test.py P :"

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() 
관련 문제