Psionman
Psionman

Reputation: 3699

Display html using a wxPython control

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()

Upvotes: 3

Views: 4514

Answers (2)

RobinDunn
RobinDunn

Reputation: 6306

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.

Upvotes: 2

Bill Bell
Bill Bell

Reputation: 21663

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()

Upvotes: 3

Related Questions