From: J. B. Jagiełło on
I've tried to create a panel with gradient background and place a
staticBox and a button on it.
Unfortunately when I placed them onto panel the width and height of DC
used by OnPaint method changed so that part of the window on the right
of rightmost widget (in my case staticBox) get not drawn.
To solve it I've created separate control (derived from wx.Window)
with the gradient and
I've placed it on the panel as a sibling of other widgets. Gradient
background fills now whole panel
but it is drawn over button and staticBox and user cannot see them
(but you can click the button).

What should I do in order to have a panel with gradient background and
controls on it?

class MiddleGradient(wx.Window):
def __init__(self, parent, id, pos, size):
wx.Window.__init__(self, parent, id, pos, size)
wx.EVT_PAINT(self, self.OnPaint)

def OnPaint(self, event):
a = wx.Colour()
b = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE)

dc = wx.PaintDC(self)
w, h = dc.GetSizeTuple()
h1 = int(h * 0.61803398874989479)
up = int(h1 * 0.38196601125010521)

dc.GradientFillLinear(wx.Rect(0, up, w, h1-up), a, b, wx.NORTH)
dc.GradientFillLinear(wx.Rect(0, h1, w, h-h1), a, b, wx.SOUTH)

class MiddlePanel(wx.Panel):
def __init__(self, parent, size):
wx.Panel.__init__(self, parent, size=size)

self.gradient = MiddleGradient(self, wx.ID_ANY, wx.Point(0, 0),
self.staticBox = wx.StaticBox(self, wx.ID_ANY, pages[0].title,
wx.Point(25, 12), wx.Size(size.width-25-24, size.height-12-12))
self.btn = wx.Button(self, wx.ID_CANCEL, "Test", wx.Point(100,100))

J. B. Jagiełło