简体   繁体   中英

multiline checkbox in wxpython

I'm working with wxpython (2.8) with python 2.5. is it possible to force a wx.CheckBox to display its label on multiple lines? I'd like to be able to do the same as wx.StaticText.Wrap(width)

See the attached example: the wx.CheckBox is 200 px wide, but it's label does not fit in this space.

Any help is really appreciated! Thanks a lot Mauro

#example starts here

import wx


class MyFrame(wx.Frame):
   def __init__(self):
       wx.Frame.__init__(self,  None, title="Hello World", size=
(300,200))

       self.panel = wx.Panel(self,  -1)
       myVSizer = wx.BoxSizer(wx.VERTICAL)

       #instantiating a checkbox 200 px wide. but the label is too
long
       cb = wx.CheckBox(self.panel,  -1,  label="This is a very very
long label for 200 pixel wide cb!",  size =wx.Size(200, -1))

       myVSizer.Add( cb, 1)

       self.panel.SetSizer(myVSizer)
       myVSizer.Layout()


app = wx.App(redirect=True)
top = MyFrame()
top.Show()
app.MainLoop()

what about something like this? Flex! (I've made it a radio button to show that it still behaves like one)

import wx
import textwrap

class MultilineRadioButton(wx.RadioButton):
        def __init__(self, parent, id=-1, label=wx.EmptyString, wrap=10, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, validator=wx.DefaultValidator, name=wx.RadioButtonNameStr):
            wx.RadioButton.__init__(self,parent,id,'',pos,size,style,validator,name)
            self._label = label
            self._wrap = wrap
            lines = self._label.split('\n')
            self._wrappedLabel = []
            for line in lines:
                self._wrappedLabel.extend(textwrap.wrap(line,self._wrap))

            self._textHOffset = 20
            dc = wx.ClientDC(self)
            font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
            dc.SetFont(font)
            maxWidth = 0
            totalHeight = 0
            lineHeight = 0
            for line in self._wrappedLabel:
                width, height = dc.GetTextExtent(line)
                maxWidth = max(maxWidth,width)
                lineHeight = height
                totalHeight += lineHeight 

            self._textHeight = totalHeight

            self.SetInitialSize(wx.Size(self._textHOffset + maxWidth,totalHeight))
            self.Bind(wx.EVT_PAINT, self.OnPaint)

        def OnPaint(self, event):
            dc = wx.PaintDC(self)
            self.Draw(dc)
            self.RefreshRect(wx.Rect(0,0,self._textHOffset,self.GetSize().height))
            event.Skip()

        def Draw(self, dc):
            dc.Clear()
            font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
            dc.SetFont(font)
            height = self.GetSize().height
            if height > self._textHeight:
                offset = height / 2 - self._textHeight / 2
            else:
                offset = 0
            for line in self._wrappedLabel:
                width, height = dc.GetTextExtent(line)
                dc.DrawText(line,self._textHOffset,offset)
                offset += height


class HFrame(wx.Frame):
   def __init__(self,pos=wx.DefaultPosition):
       wx.Frame.__init__(self,None,title="Hello World",size=wx.Size(600,400),pos=pos)

       self.panel = wx.Panel(self,-1)
       sizer = wx.BoxSizer(wx.HORIZONTAL)

       cb = RadioButton(self.panel,-1,label="This is a very very long label for the control!",wrap=10)
       sizer.Add(cb,1)

       cb = RadioButton(self.panel,-1,label="This is a very very long label for the control!",wrap=10)
       sizer.Add(cb,1)

       cb = RadioButton(self.panel,-1,label="This is a very very long label for the control!",wrap=10)
       sizer.Add(cb,1)

       self.panel.SetSizer(sizer)
       sizer.Layout()


class VFrame(wx.Frame):
   def __init__(self,pos=wx.DefaultPosition):
       wx.Frame.__init__(self,None,title="Hello World",size=wx.Size(600,400),pos=pos)

       self.panel = wx.Panel(self,-1)
       sizer = wx.BoxSizer(wx.VERTICAL)

       cb = RadioButton(self.panel,-1,label="This is a very very long label for the control!",wrap=10)
       sizer.Add(cb,1)

       cb = RadioButton(self.panel,-1,label="This is a very very long label for the control!",wrap=10)
       sizer.Add(cb,1)

       cb = RadioButton(self.panel,-1,label="This is a very very long label for the control!",wrap=10)
       sizer.Add(cb,1)

       self.panel.SetSizer(sizer)
       sizer.Layout()


app = wx.App(redirect=False)
htop = HFrame(pos=wx.Point(0,50))
htop.Show()
vtop = VFrame(pos=wx.Point(650,50))
vtop.Show()
app.MainLoop()

Changing your label to

label="This is a very very\n long label for 200\n pixel wide cb!"

should do it.

That is, put in explicit \\n characters.

替代文字

Instead of using checkbox with text, use a no label checkbox with static text for desired effect eg

import wx


class MyFrame(wx.Frame):
   def __init__(self):
      wx.Frame.__init__(self,  None, title="Hello World", size=(300,200))

      self.panel = wx.Panel(self,  -1)
      myVSizer = wx.BoxSizer(wx.VERTICAL)

      # use checkbox + static text to wrap the text
      myHSizer = wx.BoxSizer(wx.HORIZONTAL)
      cb = wx.CheckBox(self.panel,  -1,  label="")
      label = wx.StaticText(self.panel, label="This is a very very long label for 100 pixel wide cb!", size=(100,-1))
      label.Wrap(100)
      myHSizer.Add(cb, border=5, flag=wx.ALL)
      myHSizer.Add(label, border=5, flag=wx.ALL)

      myVSizer.Add(myHSizer)

      self.panel.SetSizer(myVSizer)
      myVSizer.Layout()


app = wx.App(redirect=True)
top = MyFrame()
top.Show()
app.MainLoop()

this has added benefit that with different layouts you can make text centre to checkbox, or on left or right or any other place

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