3

I am trying to display rich text (or html) in a segment of a wx python frame

I have tried the rtf control with no luck (see here). I am now trying the html route, but in the only examples I can find the html is display in a window that takes over the whole frame; for example from here

    import wx
import wx.html

class MyHtmlFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title)
        html = wx.html.HtmlWindow(self)
        if "gtk2" in wx.PlatformInfo:
            html.SetStandardFonts()

        html.SetPage(
            "Here is some <b>formatted</b> <i><u>text</u></i> "
            "loaded from a <font color=\"red\">string</font>.")


app = wx.PySimpleApp()
frm = MyHtmlFrame(None, "Simple HTML")
frm.Show()
app.MainLoop()

Is it possible to display html in a textbox or some other suitable control that I can incorporate into my application?

I want the screen to look like that below. Can the wx.TextCtrl be replaced by an HTML window or something?

import wx

class MainFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title)
        panel = MainPanel(self)
        panel.txt_comments.SetValue(
                    "Here is some <b>formatted</b>"
                    "<i><u>text</u></i> "
                    "loaded from a "
                    "<font color=\"red\">string</font>.")

class MainPanel(wx.Panel):
    def __init__(self, frame):
        wx.Panel.__init__(self, frame)

        txt_style = wx.VSCROLL|wx.HSCROLL|wx.TE_READONLY|wx.BORDER_SIMPLE
        self.txt_comments = wx.TextCtrl(self, size=(300, 150), style=txt_style)
        cmd_update = wx.Button(self, wx.ID_REFRESH)

        main_sizer = wx.BoxSizer(wx.VERTICAL)
        main_sizer.Add(self.txt_comments, flag=wx.ALL, border=10)
        main_sizer.Add(cmd_update, flag=wx.ALL, border=10)
        self.SetSizerAndFit(main_sizer)

app = wx.App()
frm = MainFrame(None, "Screen layout")
frm.Show()
app.MainLoop()

2 Answers 2

3

This must be somewhat close to an utter minimum of code.

#!/usr/bin/env python

import wx
import wx.html as html

#----------------------------------------------------------------------
ID_New  = wx.NewId()
ID_Exit = wx.NewId()
#----------------------------------------------------------------------

class MyParentFrame(wx.MDIParentFrame):
    def __init__(self):
        wx.MDIParentFrame.__init__(self, None, -1, "MDI Parent", size=(600,400))

        self.winCount = 0
        menu = wx.Menu()
        menu.Append(ID_New, "&New Window")
        menu.AppendSeparator()
        menu.Append(ID_Exit, "E&xit")

        menubar = wx.MenuBar()
        menubar.Append(menu, "&File")
        self.SetMenuBar(menubar)

        self.CreateStatusBar()

        self.Bind(wx.EVT_MENU, self.OnNewWindow, id=ID_New)
        self.Bind(wx.EVT_MENU, self.OnExit, id=ID_Exit)

    def OnExit(self, evt):
        self.Close(True)

    def OnNewWindow(self, evt):
        self.winCount = self.winCount + 1
        win = wx.MDIChildFrame(self, -1, "Child Window: %d" % self.winCount)
        self.html = html.HtmlWindow(win, -1)
        self.html.SetPage(
            "Here is some <b>formatted</b> <i><u>text</u></i> "
            "loaded from a <font color=\"red\">string</font>.")

#----------------------------------------------------------------------

if __name__ == '__main__':
    class MyApp(wx.App):
        def OnInit(self):
            frame = MyParentFrame()
            frame.Show(True)
            self.SetTopWindow(frame)
            return True

    app = MyApp(False)
    app.MainLoop()

I expect the main lines to note are these:

    win = wx.MDIChildFrame(self, -1, "Child Window: %d" % self.winCount)
    self.html = html.HtmlWindow(win, -1)
    self.html.SetPage(
        "Here is some <b>formatted</b> <i><u>text</u></i> "
        "loaded from a <font color=\"red\">string</font>.")
  • win is the frame in which you want to house the HTMLWindow.
  • Notice that win is the first parameter to HTMLWindow.

I used wxWindow quite a bit several years ago, and I've lost most of my skills. Now I remember that the secret to getting a leg up is to start with the demo codes. I used a couple of them this time.

Edit on the basis of comments:

import wx
import wx.html as html

class MainFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title)
        panel = MainPanel(self)

class MainPanel(wx.Panel):
    def __init__(self, frame):
        wx.Panel.__init__(self, frame)

        txt_style = wx.VSCROLL|wx.HSCROLL|wx.TE_READONLY|wx.BORDER_SIMPLE
        self.html = html.HtmlWindow(self, -1, size=(300, 150), style=txt_style)
        self.html.SetPage(
                    "Here is some <b>formatted</b>"
                    "<i><u>text</u></i> "
                    "loaded from a "
                    "<font color=\"red\">string</font>.")

app = wx.App()
frm = MainFrame(None, "Screen layout")
frm.Show()
app.MainLoop()
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks Bill, but I want a "control" that handles HTML, not the whole window. Is this possible? I have updated my question to include an example screen showing the layout
There must be something I'm still missing. If you run the code that appears under that 'example screen' you will get the 'example screen'.
Oh dear. Chinese whispers! I just want the html to appear where the txtCtrl appears, not the whole window
Perhaps you mean by 'control' that you want to make an object that can contain HTML and respond to clicks, etc? Then what I suggested above does that, in the sense that MDIChildFrame inherits from Frame. You can make a 'control' by putting an HTMLWindow in a Frame, or anything that inherits from Frame, as I did. If you want to see more about events then have a look at the demo for HTMLWindow.
As you say, Chinese whispers.
|
2

wx.html.HtmlWindow or wx.html2.WebView are much like other child widgets in wxPython, in that they need a parent, and the size and position need to be managed in some way, and so on. That also means that you can replace the use of TextCtrl in your sample with one of those widgets, and replace SetValue with SetPage and it should work the way you want. See the docs for specifics and give it a try.

1 Comment

Yes. Thanks. Works perfectly. Can't now see why I had a problem

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.