Thank you for your input, Dietmar!
I eventually came up with a workable solution by subclassing the static text widget with help from Google’s Gemini chat bot.
The solution is to create an OnPaint() method in the subclass and bind it to EVT_PAINT event.
Inside of OnPaint, an instance of the BufferedPaintDC class is created.
This allows the text to be copied and repainted at an offset.
I’ve included a bare bones implementation below:
class BorderedLabel( wx.StaticText ):
def init( self, parent, label=“”, offsets=(0, 0), *args, **kwargs ):
self.offsets = offsets
# Add wx.FULL_REPAINT_ON_RESIZE to ensure the border redraws smoothly,
super().__init__( parent, label=label, *args, **kwargs )
# Bind the drawing event
self.Bind( wx.EVT_PAINT, self.OnPaint )
def OnPaint( self, event ):
dc = wx.BufferedPaintDC( self )
dc.SetBackground(wx.Brush( self.GetBackgroundColour() ))
dc.Clear( )
x_offset, y_offset = self.offsets
dc.DrawText( self.GetLabel(), x_offset, y_offset)
def setOffsets( self, offsets=(0,0) ):
self.offsets = ( offsets )
Respectfully, I would argue that that is the primary purpose of a static text box. I would assume that a widget with the sole purpose to display text should have as many options as possible to display that text.
In hindsight, I should have given a more detailed description of my requirements.
I am creating a dynamic text display of a 12 tone matrix.
The most straightforward implementation is a 12 by 12 grid of text boxes displaying different forms of the 12 pitches in Western music.
Your recommendation was to use a TextCtrl widget, but that widget is for text input. Text input can be inhibited, but it still displays a cursor inside the box. A screenshot after adding subclassing appears below.