简体   繁体   中英

Graphics issue upon resizing a panel in wxPython

I am working with python v2.7 and wxPython v3.0 on Windows 8 OS. (Sorry for the confusing title. I have no idea what the title should be. I shall try my best to explain my problem in detail.)

In my app I have a scrolled panel with a background image. This panel is named as mainPanel in the code snippet. This mainPanel contains other panels named as myPanelA and myPanelB that have transparent background. These panels myPanelA and myPanelB contains sizers that are containing some buttons. PS: This is just a sample of my real world app. In my real world app I have many different panels and buttons. In this case the patches are more big and annoying. :(

Problem : When I resize my windows horizontally, some times (In my real world app it is very frequent as compared to this sample app.) I see blank patches in my App windows as shown in sample images below. How can I avoid this? It would be great if some one can test this and report if they have same problem on their machine (Just to be sure this is not Windows OS issue. I tested on Windows 7 too, it has the same problem.)

Update: Simply resize the window and scroll vertically, you'll see the patches quite often.

Sample Images : The patch is pointed by an arrow. 例1例题示例3

Code: Here is my code sample for playing around. The background image can be downloaded from here. greensquares.jpg

import wx
import wx.lib.scrolledpanel

class gui(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, None, id, title, style=wx.DEFAULT_FRAME_STYLE)
        mainPanel = wx.lib.scrolledpanel.ScrolledPanel(self, -1)
        mainPanel.SetupScrolling()
        myImage = wx.Image('greensquares.jpg', wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        myBitmap = wx.StaticBitmap(mainPanel, -1, myImage, (0, 0))
        myPanelA = wx.Panel(myBitmap, -1, style=wx.TRANSPARENT_WINDOW, pos=(100,0), size=(150,150))
        wx.StaticText(myPanelA, -1, '     MyPanelA    ')
        myButton1A = wx.Button(myPanelA, -1, size=(20,20))
        myButton2A = wx.Button(myPanelA, -1, size=(20,20))
        mySizerA = wx.BoxSizer(wx.HORIZONTAL)
        mySizerA.Add(myButton1A, 0, wx.ALL, 20)
        mySizerA.Add(myButton2A, 0, wx.ALL, 20)
        myPanelA.SetSizer(mySizerA)
        myPanelA.Layout()

        myPanelB = wx.Panel(myBitmap, -1, style=wx.TRANSPARENT_WINDOW, pos=(100,130), size=(250,200))
        wx.StaticText(myPanelB, -1, '      MyPanelB    ')
        myButton1B = wx.Button(myPanelB, -1, size=(20,20))
        myButton2B = wx.Button(myPanelB, -1, size=(20,20))
        myButton3B = wx.Button(myPanelB, -1, size=(20,20))
        myButton4B = wx.Button(myPanelB, -1, size=(20,20))
        mySizerB1 = wx.BoxSizer(wx.HORIZONTAL)
        mySizerB1.Add(myButton1B, 0, wx.ALL, 20)
        mySizerB1.Add(myButton2B, 0, wx.ALL, 20)
        mySizerB1.Add(myButton3B, 0, wx.ALL, 20)
        mySizerB1.Add(myButton4B, 0, wx.ALL, 20)
        myButton5B = wx.Button(myPanelB, -1, size=(20,20))
        myButton6B = wx.Button(myPanelB, -1, size=(20,20))
        myButton7B = wx.Button(myPanelB, -1, size=(20,20))
        myButton8B = wx.Button(myPanelB, -1, size=(20,20))
        mySizerB2 = wx.BoxSizer(wx.HORIZONTAL)
        mySizerB2.Add(myButton5B, 0, wx.ALL, 20)
        mySizerB2.Add(myButton6B, 0, wx.ALL, 20)
        mySizerB2.Add(myButton7B, 0, wx.ALL, 20)
        mySizerB2.Add(myButton8B, 0, wx.ALL, 20)
        mySizerC = wx.BoxSizer(wx.VERTICAL)
        mySizerC.Add(mySizerB1)
        mySizerC.Add(mySizerB2)
        myPanelB.SetSizer(mySizerC)
        myPanelB.Layout()

if __name__ == '__main__':
    app = wx.App()
    frame = gui(parent=None, id=-1, title="My-App")
    frame.Show()
    app.MainLoop()

Thank you for your time.

I added a Update method to your panels, which seems to have fixed the issue on my side.

import wx
import wx.lib.scrolledpanel

class gui(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, None, id, title, style=wx.DEFAULT_FRAME_STYLE)
        mainPanel = wx.lib.scrolledpanel.ScrolledPanel(self, -1)
        mainPanel.SetupScrolling()
        myImage = wx.Image('greensquares.jpg', wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        myBitmap = wx.StaticBitmap(mainPanel, -1, myImage, (0, 0))
        self.myPanelA = wx.Panel(myBitmap, -1, style=wx.TRANSPARENT_WINDOW, pos=(100,0), size=(150,150))
        wx.StaticText(self.myPanelA, -1, '     self.myPanelA    ')
        myButton1A = wx.Button(self.myPanelA, -1, size=(20,20))
        myButton2A = wx.Button(self.myPanelA, -1, size=(20,20))
        mySizerA = wx.BoxSizer(wx.HORIZONTAL)
        mySizerA.Add(myButton1A, 0, wx.ALL, 20)
        mySizerA.Add(myButton2A, 0, wx.ALL, 20)
        self.myPanelA.SetSizer(mySizerA)
        self.myPanelA.Layout()

        self.myPanelB = wx.Panel(myBitmap, -1, style=wx.TRANSPARENT_WINDOW, pos=(100,130), size=(250,200))
        wx.StaticText(self.myPanelB, -1, '      self.myPanelB    ')
        myButton1B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton2B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton3B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton4B = wx.Button(self.myPanelB, -1, size=(20,20))
        mySizerB1 = wx.BoxSizer(wx.HORIZONTAL)
        mySizerB1.Add(myButton1B, 0, wx.ALL, 20)
        mySizerB1.Add(myButton2B, 0, wx.ALL, 20)
        mySizerB1.Add(myButton3B, 0, wx.ALL, 20)
        mySizerB1.Add(myButton4B, 0, wx.ALL, 20)
        myButton5B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton6B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton7B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton8B = wx.Button(self.myPanelB, -1, size=(20,20))
        mySizerB2 = wx.BoxSizer(wx.HORIZONTAL)
        mySizerB2.Add(myButton5B, 0, wx.ALL, 20)
        mySizerB2.Add(myButton6B, 0, wx.ALL, 20)
        mySizerB2.Add(myButton7B, 0, wx.ALL, 20)
        mySizerB2.Add(myButton8B, 0, wx.ALL, 20)
        mySizerC = wx.BoxSizer(wx.VERTICAL)
        mySizerC.Add(mySizerB1)
        mySizerC.Add(mySizerB2)
        self.myPanelB.SetSizer(mySizerC)
        self.myPanelB.Layout()

        self.Bind(wx.EVT_SIZE, self.OnResize)

    def OnResize(self, e):
        self.myPanelA.Update()
        self.myPanelB.Update()
        e.Skip()

if __name__ == '__main__':
    app = wx.App()
    frame = gui(parent=None, id=-1, title="My-App")
    frame.Show()
    app.MainLoop()

I finally found the solution. In addition to what multiphrenic has suggested I have also binded the scroll event to a the OnResize() . So, that when ever any scroll event EVT_SCROLL occurs the panels will be updated too. It is working fine on Windows7, 8 OS with python v2.7 and wxPython v3.0.

Working code:

import wx
import wx.lib.scrolledpanel

class gui(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, None, id, title, style=wx.DEFAULT_FRAME_STYLE)
        mainPanel = wx.lib.scrolledpanel.ScrolledPanel(self, -1)
        mainPanel.SetupScrolling()
        myImage = wx.Image('greensquares.jpg', wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        myBitmap = wx.StaticBitmap(mainPanel, -1, myImage, (0, 0))
        self.myPanelA = wx.Panel(myBitmap, -1, style=wx.TRANSPARENT_WINDOW, pos=(100,0), size=(150,150))
        wx.StaticText(self.myPanelA, -1, 'self.myPanelA')
        myButton1A = wx.Button(self.myPanelA, -1, size=(20,20))
        myButton2A = wx.Button(self.myPanelA, -1, size=(20,20))
        mySizerA = wx.BoxSizer(wx.HORIZONTAL)
        mySizerA.Add(myButton1A, 0, wx.ALL, 20)
        mySizerA.Add(myButton2A, 0, wx.ALL, 20)
        self.myPanelA.SetSizer(mySizerA)
        self.myPanelA.Layout()

        self.myPanelB = wx.Panel(myBitmap, -1, style=wx.TRANSPARENT_WINDOW, pos=(100,130), size=(250,200))
        wx.StaticText(self.myPanelB, -1, 'self.myPanelB')
        myButton1B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton2B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton3B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton4B = wx.Button(self.myPanelB, -1, size=(20,20))
        mySizerB1 = wx.BoxSizer(wx.HORIZONTAL)
        mySizerB1.Add(myButton1B, 0, wx.ALL, 20)
        mySizerB1.Add(myButton2B, 0, wx.ALL, 20)
        mySizerB1.Add(myButton3B, 0, wx.ALL, 20)
        mySizerB1.Add(myButton4B, 0, wx.ALL, 20)
        myButton5B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton6B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton7B = wx.Button(self.myPanelB, -1, size=(20,20))
        myButton8B = wx.Button(self.myPanelB, -1, size=(20,20))
        mySizerB2 = wx.BoxSizer(wx.HORIZONTAL)
        mySizerB2.Add(myButton5B, 0, wx.ALL, 20)
        mySizerB2.Add(myButton6B, 0, wx.ALL, 20)
        mySizerB2.Add(myButton7B, 0, wx.ALL, 20)
        mySizerB2.Add(myButton8B, 0, wx.ALL, 20)
        mySizerC = wx.BoxSizer(wx.VERTICAL)
        mySizerC.Add(mySizerB1)
        mySizerC.Add(mySizerB2)
        self.myPanelB.SetSizer(mySizerC)
        self.myPanelB.Layout()

        self.Bind(wx.EVT_SIZE, self.OnResize)
        self.Bind(wx.EVT_SCROLL, self.OnResize)

    def OnResize(self, e):
        self.myPanelA.Update()
        self.myPanelB.Update()
        e.Skip()

if __name__ == '__main__':
    app = wx.App()
    frame = gui(parent=None, id=-1, title="My-App")
    frame.Show()
    app.MainLoop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM