How to insert <br> into RichTextCtrl

Hi,
I am trying to write some text in the RichTextCtrl and I am having problems with line breaks.

What I need to do is start a paragraph write some text on a line, end that line an continue directly under it, write more text and then end the paragraph.
In HTML it would look like this:
<p>
text on a line<br>text on second line.
</p>

So far I tried these:

  1. WriteText(’\n’) This ends the paragraph and jumps to a new one.
  2. Newline() Does the same thing as \n and os.linesep
  3. LineBreak() Kind of looks like what I needed, but is not, it behaves differently. You can not insert this on the last line of a paragraph.

Here is an example code:
Try to insert Shift+Enter on the last line.

import wx
import wx.richtext as rt


class RichTextFrame(wx.Frame):
    def __init__(self, *args, **kw):
        wx.Frame.__init__(self, *args, **kw)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.rtc = rt.RichTextCtrl(self, style=wx.VSCROLL | wx.HSCROLL | wx.NO_BORDER)
        self.sizer.Add(self.rtc, 1, flag=wx.EXPAND)
        self.SetSizer(self.sizer)
        self._stylesheet = rt.RichTextStyleSheet()
        self._stylesheet.SetName('Stylesheet')
        self._create_styles()
        self._insert_sample_text()

    def _create_styles(self) -> None:
        """
        Create styles for rich text control.
        :return: None
        """
        # Normal style
        stl_paragraph: rt.RichTextAttr = self.rtc.GetDefaultStyleEx()
        stl_paragraph.SetParagraphSpacingBefore(10)
        stl_paragraph.SetParagraphSpacingAfter(10)
        style_paragraph: rt.RichTextParagraphStyleDefinition = rt.RichTextParagraphStyleDefinition('par')
        style_paragraph.SetStyle(stl_paragraph)
        style_paragraph.SetNextStyle('par')
        self._stylesheet.AddParagraphStyle(style_paragraph)
        self.rtc.ApplyStyle(style_paragraph)
        self.rtc.SetDefaultStyle(stl_paragraph)

        # Link style
        stl_link = rt.RichTextAttr()
        stl_link.SetFlags(wx.TEXT_ATTR_URL)
        stl_link.SetFontUnderlined(True)
        stl_link.SetTextColour(wx.BLUE)
        style_link: rt.RichTextCharacterStyleDefinition = rt.RichTextCharacterStyleDefinition('url')
        style_link.SetStyle(stl_link)
        self._stylesheet.AddCharacterStyle(style_link)

    def _insert_link(self, text: str, link_id: str) -> None:
        """
        Insert a link into text at current position.
        :param text: The visible text.
        :param link_id: The ID of the link
        :return: None
        """
        self.rtc.BeginStyle(self._stylesheet.FindCharacterStyle('url').GetStyle())
        self.rtc.BeginURL(link_id)
        self.rtc.WriteText(text)
        self.rtc.EndURL()
        self.rtc.EndStyle()

    def _insert_sample_text(self) -> None:
        """
        Insert sample text.
        :return: None
        """
        self.rtc.ApplyStyle(self._stylesheet.FindParagraphStyle('par'))
        self.rtc.BeginParagraphStyle('par')
        self.rtc.WriteText('paragraph 1, sample of a longer text for testing url creation ')
        self.rtc.LineBreak()
        self.rtc.WriteText('paragraph 1, more sample of a longer text for testing url creation ')
        self._insert_link('www.google.com', 'link from code')
        self.rtc.EndParagraphStyle()

        self.rtc.Newline()

        self.rtc.ApplyStyle(self._stylesheet.FindParagraphStyle('par'))
        self.rtc.BeginParagraphStyle('par')
        self._insert_link('www.google.com', '42')
        self.rtc.WriteText(' paragraph 2 adding some text after a link')
        self.rtc.LineBreak()
        self.rtc.WriteText(' some more text after a line break in code')
        self.rtc.EndParagraphStyle()

        self.rtc.Newline()


class MyApp(wx.App):
    """
    Main class for running the gui
    """

    def __init__(self):
        wx.App.__init__(self)
        self.frame = None

    def OnInit(self):
        self.frame = RichTextFrame(None, -1, "RichTextCtrl", size=(900, 500), style=wx.DEFAULT_FRAME_STYLE)
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True


if __name__ == "__main__":
    app = MyApp()
    app.MainLoop()

I played with it in the RTC sample in the demo. The only possible glitch with the line break that I saw was that there needs to be something after the break before the line was actually broken. When trying it at the end of the document it means that after the Shift-Enter you need to type one more character. When you do the cursor moves to the next line and the typed character is shown there. Depending on your point of view this could be a bug, or it could be working as was intended, since if there is nothing after the line-break then there isn’t anything to break.

You can file a ticket about this (if there isn’t already one there) on https://trac.wxwidgets.org/ if you don’t agree.

1 Like

Thanks.

After studying the LineBreak a bit more I think it actually does something else that what I though it does.
“A line break forces wrapping within a paragraph, and can be introduced by using this function, by appending the Char value RichTextLineBreakChar to text content, or by typing Shift-Return.”

Try this:
Press Shift-Enter at the end of the first line, then go two left arrows back and start typing. The cursor will move to the next line.
Go to the last line, press Shift-Enter in the middle of the line and then type enough words to finish the line. At one point the line will break at the position of the Shift-Enter.

It is consistent with what the docstring says, but it is weird to be honest. It does not make much sense to me from like a text editing point of view.

Basically what I need to be able to do is a plain ordinary new line in the same paragraph.
Currently when you press enter or insert \n or NewLine() or os.linesep it jumps to a new paragraph. I just need to end the line before hitting the end of the window. :smiley:

See: