在Windows上wx python图像刷新

时间:2016-08-20 08:00:10

标签: linux windows image wxpython

我有一个涉及显示多个图像的应用程序。这可以像我在Linux上所期望的那样工作,但是在Windows上有一个令人讨厌的闪存,因为图像被绘制。这最好看作屏幕左上角的一个小方块,闪烁的颜色出现。我没有以正确的方式接近这个要求吗?或者是否有一些我应该应用的修复来克服Windows效果?或者它只是我在Windows上的版本(我只有一个测试它:Windows 7旗舰版)?

我在 refresh_sizer_cell 中尝试过冻结和解冻,但它并没有像我预期的那样行事

import wx


class ImageSizer(wx.Frame):
    BACKGROUND_COLOUR = (246, 244, 242)
    def __init__(self, parent, title):
        super(ImageSizer, self).__init__(parent, title=title)

        self.main_sizer = wx.GridBagSizer()
        self.SetSizer(self.main_sizer)

        cmd_reset = wx.Button(self, label='Reset')
        cmd_reset.Bind(wx.EVT_BUTTON, self.on_cmd_reset_click)

        cmd_cancel = wx.Button(self, label='Cancel')
        cmd_cancel.Bind(wx.EVT_BUTTON, self.on_cmd_cancel_click)

        self.main_sizer.Add((400, 0), pos=(0, 0), span=(1, 2))    # dummy to position Available
        self.main_sizer.Add((0, 100), pos=(1, 0), span=(1, 1))    # dummy to position Buttons
        self.main_sizer.Add(cmd_reset, pos=(2, 2), flag=wx.LEFT | wx.TOP, border=10)
        self.main_sizer.Add(cmd_cancel, pos=(2, 3), flag=wx.RIGHT | wx.BOTTOM | wx.TOP | wx.ALIGN_RIGHT, border=10)

        self.SetBackgroundColour(self.BACKGROUND_COLOUR)
        self.shape_types = {'available': 0, 'selected': 1}
        self.available_shapes = []
        self.selected_shapes = []
        self.initialise()
        self.Center()
        self.Fit()
        self.Show()

    def initialise(self):
        self.available_shapes = ['square', 'circle', 'triangle', 'cross']
        self.selected_shapes = []
        self.display_images()

    def display_images(self):
        available_sizer = ShapeSizer(self, self.available_shapes, self.shape_types['available'])
        self.refresh_sizer_cell(self.main_sizer, available_sizer, (1, 2), (1, 3))
        selected_sizer = ShapeSizer(self, self.selected_shapes, self.shape_types['selected'])
        self.refresh_sizer_cell(self.main_sizer, selected_sizer, (1, 1), (2, 1))
        self.Layout()

    @staticmethod
    def refresh_sizer_cell(sizer, item, pos, span, flag=wx.ALL, border=10):
        old_item = sizer.FindItemAtPosition(pos)
        if old_item is not None and old_item.IsWindow():
            old_item.GetWindow().Hide()
            sizer.Detach(old_item.GetWindow())
        sizer.Add(item, pos=pos, span=span, flag=flag, border=border)

    def on_available_shape_double_click(self, event):
        shape = event.GetEventObject().GetName()
        self.available_shapes.remove(shape)
        self.selected_shapes.append(shape)
        self.display_images()

    def on_selected_shape_double_click(self, event):
        shape = event.GetEventObject().GetName()
        self.selected_shapes.remove(shape)
        self.available_shapes.append(shape)
        self.display_images()

    def on_cmd_reset_click(self, event):
        self.initialise()

    def on_cmd_cancel_click(self, event):
        self.Destroy()


class ShapeSizer(wx.Panel):
    def __init__(self, parent, shapes, shape_type):
        wx.Panel.__init__(self, parent, id = wx.ID_ANY)

        if shape_type == parent.shape_types['available']:
            size = 40
            action = parent.on_available_shape_double_click
        else:
            size = 80
            action = parent.on_selected_shape_double_click
        panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
        shapes.sort()
        for shape in shapes:
            bitmap = wx.Bitmap(shape + '.png', wx.BITMAP_TYPE_PNG)
            bitmap = self.scale_bitmap(bitmap, size, size)
            img = wx.StaticBitmap(self, wx.ID_ANY, bitmap, name=shape)
            img.Bind(wx.EVT_LEFT_DCLICK, action)
            panel_sizer.Add(img, flag=wx.RIGHT, border=10)
        self.SetSizer(panel_sizer)

    @staticmethod
    def scale_bitmap(bitmap, width, height):
          image = wx.ImageFromBitmap(bitmap)
          image = image.Scale(width, height, wx.IMAGE_QUALITY_HIGH)
          result = wx.BitmapFromImage(image)
          return result

if __name__  ==  '__main__':
        app = wx.App()
        ImageSizer(None, title='Image Sizer')
        app.MainLoop()

以下是图片:

circle.png

cross.png

square.png

triangle.png

1 个答案:

答案 0 :(得分:1)

每次双击某个形状时,程序都会创建面板及其wx.StaticBitmap窗口小部件的新实例,这是您看到的这些新实例,因为它们最初是使用较小的默认大小创建的,然后是由下一个布局重新定位。相反,您应该重新组织事物,这样您只需创建一次面板集,并且随着形状选择的状态发生变化,您可以让现有面板自行更新。这将大大减少用户可见的闪烁。