Sometimes it's nice to have a simple background pattern in a wx Panel, Window of Frame. The following example uses a rather dark colored hatch pattern. You'll probably want to use a more subtle color. Several simple automatically generated patterns are available - see the various wx.Brush() styles when using dc.DrawRectangle to draw the pattern.
If you want full control of the background pattern you can substitute a series of dc.DrawLine() and other dc drawing calls to draw a pattern of your choosing. Consider how wxPython draws the hatch pattern shown below. It's not very difficult to code something similar yourself.
Class variable [ self.hatchedWinBorder ] is set to 15 in the demo. Set it to 0 to make the hatched window fill the parent Frame.
In the next shot the frame was resized which not only resized the hatched window, but also redrew it using a dc. Notice how the hatch line spacings remain the same. The hatched window's parent container control, the Frame, is responsible for the size and placement of the hatched window while the window redraws itself on the Frame's resize events.
Within the Frame class definition :
1 def OnSize( self, event ) : 2 """ 3 Define/redefine the position and size of the hatched window 4 A wx.EVT_SIZE event generates a wx.EVT_PAINT event in objects 5 # created from the class (instantiated from the class definition). 6 7 Every wx.EVT_SIZE event generates a wx.EVT_PAINT event. 8 This paint handler is just a pass-through. 9 """ 10 11 self.CenterHatchedWinInHwPanel() 12 13 event.Skip() 14 15 #end def 16 17 #---------------------------------- 18 19 def CenterHatchedWinInHwPanel( self ) : 20 21 # The slider value [0..100] will set the hatched window size to [0..100%] 22 # of each client axis containing self.hwPanel 23 hwPanelWidth, hwPanelHeight = self.hwPanel.GetClientSize() 24 25 # Resize hatchedWin 26 newHwinWidth = int( (self.sliderValue / 100.0) * hwPanelWidth + 0.5) 27 newHwinHeight = int( (self.sliderValue / 100.0) * hwPanelHeight + 0.5) 28 newWinSize = (newHwinWidth, newHwinHeight) 29 self.hatchedWin.SetSize( newWinSize ) 30 31 # Reposition hatchedWin 32 newHwinPosX = (hwPanelWidth - newHwinWidth) / 2 33 newHwinPosY = (hwPanelHeight - newHwinHeight) / 2 34 newHwinPos = (newHwinPosX, newHwinPosY) 35 self.hatchedWin.SetPosition ( newHwinPos ) 36 37 self.Layout() # Resize and reposition its controls. 38 39 self.hwPanel.Refresh( False ) 40 41 #end def
The hatched panel's wx.EVT_PAINT handler :
1 def OnPaint( self, event=None ) : 2 3 dc = wx.PaintDC( self ) 4 selfSizeX, selfSizeY = self.GetSize() 5 6 # Define the background pattern. The HatchedWindow background color is retained. 7 hatchColor = (0, 75, 0) # dark green - use any color 8 dc.SetPen( wx.Pen( hatchColor, 1 ) ) 9 bgPattern = wx.BDIAGONAL_HATCH # See the various wx.Brush() styles. 10 dc.SetBrush( wx.Brush( hatchColor, bgPattern ) ) 11 12 dc.DrawRectangle( 0, 0, selfSizeX, selfSizeY ) 13 14 """ 15 # Overdraw the original rectangle outline with another color. 16 dc.SetPen( wx.Pen( 'wHiTe', 5 ) ) # use any color 17 dc.SetBrush( wx.Brush( 'BluE', wx.TRANSPARENT ) ) # Leave the interior intact 18 dc.DrawRectangle( 0, 0, selfSizeX, selfSizeY ) 19 """ 20 21 event.Skip() 22 23 #end OnPaint def
The next demo gets fancier by managing the HatchedWindow's size by a slider position. The wx.Slider is positioned at the bottom of the Frame using a sizer. The rest of the Frame client area is taken up by a second panel that holds the hatched window. The HatchedWindow's size and position are calculated using the current slider position and the current panel dimensions. How it all works is explained in the comments. It's important to note that no sizer can easily manage the position of the hatched window because a sizer's most important function is to auto-size, but the size must be calculated from the slider position :
1 def CenterHatchedWinInHwPanel( self ) : 2 3 # The slider value [0..100] will set the hatched window size to [0..100%] 4 # of both client axes of self.hwPanel that contains self.hwPanel 5 hwPanelWidth, hwPanelHeight = self.hwPanel.GetClientSize() 6 7 # Resize hatchedWin using the slider position value. 8 newHwinWidth = int( (self.sliderValue / 100.0) * hwPanelWidth + 0.5) 9 newHwinHeight = int( (self.sliderValue / 100.0) * hwPanelHeight + 0.5) 10 newWinSize = (newHwinWidth, newHwinHeight) 11 self.hatchedWin.SetSize( newWinSize ) 12 13 # Reposition hatchedWin 14 newHwinPosX = (hwPanelWidth - newHwinWidth) / 2 15 newHwinPosY = (hwPanelHeight - newHwinHeight) / 2 16 newHwinPos = (newHwinPosX, newHwinPosY) 17 self.hatchedWin.SetPosition ( newHwinPos ) 18 19 self.Layout() # The sizer will resize and reposition its controls. 20 21 self.hwPanel.Refresh( False ) 22 23 #end def
When the Frame's size is changed the size of both the hatched window and the slider are adjusted. The self.frmPnl_vSzr is configured to keep the slider's height to stay fixed while the size of self.frmPnl_vSzr is fully flexible. The hatched window's "manual" sizing and positioning code maintains the ratio of the lengths of the hatched window ( its "aspect ratio" ) to remain constant on slider changes.
Despite changes in the Frame's size the aspect ratio of the hatched window is fixedfor any given slider value.
--- Ray Pasco 2011, July
Send your questions and comments to pascor(at)verizon(dot)net