Reputation: 66063
I'm attempting to make a wx.Panel
derived class that will display rotated text. However, the moment this widget is added to a wx.Sizer
, the text no longer displays. When it is added directly to a wx.Frame
, the text displays but is truncated. What am I doing wrong?
import wx
class Win(wx.Frame):
def __init__(self):
super(Win, self).__init__(None, wx.ID_ANY)
self.p = wx.Panel(self, wx.ID_ANY)
self.p.SetSizer(wx.BoxSizer())
self.rt = RotatedText(self.p, wx.ID_ANY, 'hello', 90)
self.p.GetSizer().Add(self.rt)
class RotatedText(wx.Window):
def __init__(self, parent, id, text, angle, font=None, *args, **kwargs):
super(RotatedText, self).__init__(parent, id, *args, **kwargs)
self.text = text
self.font = font
self.angle = angle
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_SIZE, self.OnSize)
def repaint(self, dc):
if self.font:
dc.SetFont(self.font)
text_height, text_width = dc.GetTextExtent(self.text)
dc.SetTextForeground(wx.BLACK)
dc.DrawText(self.text, 0, 0)
def OnPaint(self, event):
dc = wx.PaintDC(self)
self.repaint(dc)
event.Skip()
def OnSize(self, event):
dc = wx.ClientDC(self)
self.repaint(dc)
event.Skip()
app = wx.App()
win = Win()
win.Show()
app.MainLoop()
Note that I use dc.DrawText()
instead of dc.DrawRotatedText()
since I'm attempting to reduce the problem down to it's simplest form. Eventually, I do wish to use dc.DrawRotatedText()
.
Upvotes: 1
Views: 549
Reputation: 1236
When creating your custom window give it an explicit size. I've included an example below.
What is happening is since the custom window doesn't have any controls associated it with it the sizer is assuming it is empty and "squishing" it to as small a size as possible (probably 0,0).
I also added the draw rotated text method call and some arbitrary sizes. You can of course play around with those until it suits your needs.
import wx
class Win(wx.Frame):
def __init__(self):
super(Win, self).__init__(None, wx.ID_ANY)
self.p = wx.Panel(self, wx.ID_ANY)
self.p.SetSizer(wx.BoxSizer())
# set the minimum size when creating the custom window so that the sizer doesn't "squash" it to 0,0
self.rt = RotatedText(self.p, wx.ID_ANY, 'hello', 90,size=(60,60))
self.p.GetSizer().Add(self.rt)
class RotatedText(wx.Window):
def __init__(self, parent, id, text, angle, font=None, *args, **kwargs):
super(RotatedText, self).__init__(parent, id, *args, **kwargs)
self.text = text
self.font = font
self.angle = angle
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_SIZE, self.OnSize)
# set our minimum size based on the text with
dc = wx.MemoryDC()
self.text_width, self.text_height= dc.GetTextExtent(self.text)
# height and width are reversed since we are drawing text vertically
self.SetMinSize((self.text_height,self.text_width))
def repaint(self, dc):
if self.font:
dc.SetFont(self.font)
text_width, text_height = dc.GetTextExtent(self.text)
dc.SetTextForeground(wx.BLACK)
#dc.DrawText(self.text, 0, 0) # change this line to start drawing from bottom to top beginning 60 units from top
dc.DrawRotatedText(self.text, 0, self.text_width, self.angle)
def OnPaint(self, event):
dc = wx.PaintDC(self)
self.repaint(dc)
event.Skip()
def OnSize(self, event):
dc = wx.ClientDC(self)
self.repaint(dc)
event.Skip()
app = wx.App()
win = Win()
win.Show()
app.MainLoop()
Upvotes: 3