wxHTML for Beginners
By Abhijit Belapurkar2004-10-30
The World's Most Basic Browser
The first step is to assemble the minimum code necessary to support an application using the wxHtml widget. The following code implements a basic wxPython application with an wxHtml widget as the contents of the main window.
Listing 1. Bare-bones example browser code
from wxPython.wx import *Assuming you have wxPython correctly installed, running the above code in your Python interpreter will result in a single large window with an empty white panel (the wxHtml widget). If you get any syntax errors, check for whitespace issues -- especially if you cut-and-pasted the code into your interpreter or editor. If your Python interpreter complains about not being able to import wxPython, check your installation to make sure that it is set up properly.
from wxPython.html import *
import os,sys
class exHtmlWindow(wxHtmlWindow):
def __init__(self, parent, id, frame):
wxHtmlWindow.__init__(self,parent,id)
class exHtmlPanel(wxPanel):
def __init__(self, parent, id, frame):
wxPanel.__init__(self,parent,-1)
self.html = exHtmlWindow(self, -1, frame)
self.box = wxBoxSizer(wxVERTICAL)
self.box.Add(self.html, 1, wxGROW)
self.SetSizer(self.box)
self.SetAutoLayout(true)
class exFrame (wxFrame):
def __init__(self, parent, ID, title):
wxFrame.__init__(self,parent,ID,title,wxDefaultPosition,wxSize(600,750))
panel = exHtmlPanel(self, -1, self)
class exApp(wxApp):
def OnInit(self):
frame = exFrame(NULL, -1, "Example Browser")
frame.Show(true)
self.SetTopWindow(frame)
return true
app = exApp(0)
app.MainLoop()
Of course, as soon as you launch the browser, it becomes immediately evident that we're missing something... such as a mechanism by which to load pages. For some applications, this very basic setup may actually be enough -- the user doesn't need to choose his own pages if you already know what you want to deliver. A simple change would be to pass an extra argument to exHtmlPanel, which would be the page you want to access:
Listing 2. Modifying exHtmlPanel to load page
class exHtmlPanel(wxPanel):In the interest of making something a little more standalone and browser-like, we'll expand the ttHtmlPanel class to add some buttons to do standard browser tasks. Of course, if you're actually planning to build a real browser application, you might want to put some more thought into GUI design and usability than we did here.
+ def __init__(self, parent, id, frame, file):
wxPanel.__init__(self, parent, -1)
self.html = exHtmlWindow(self, -1, frame)
self.box = wxBoxSizer(wxVERTICAL)
self.box.Add(self.html, 1, wxGROW)
self.SetSizer(self.box)
self.SetAutoLayout(true)
+ self.html.LoadPage(file)
Listing 3. Modifying ttHtmlPanel to add buttons
class ttHtmlPanel(wxPanel):If you've previously used wxPython, or any other Python graphics toolkit, you can see that all we've done is add another container to the panel and put four buttons in it, with callbacks to the added methods in the exHtmlPanel class. The base wxHtml class handily manages the history for us, so OnBack and OnForward are simply calls to the base methods.
def __init__(self, parent, id, frame):
wxPanel.__init__(self, parent, -1)
self.frame = frame
self.cwd = os.path.split(sys.argv[0])[0]
if not self.cwd:
self.cwd = os.getcwd
self.html = ttHtmlWindow(self, -1, self.frame)
self.box = wxBoxSizer(wxVERTICAL)
self.box.Add(self.html, 1, wxGROW)
subbox = wxBoxSizer(wxHORIZONTAL)
btn = wxButton(self, 1202, "Load File")
EVT_BUTTON(self, 1202, self.OnLoadFile)
subbox.Add(btn, 1, wxGROW | wxALL, 2)
btn = wxButton(self, 1203, "Load Page")
EVT_BUTTON(self, 1203, self.OnLoadPage)
subbox.Add(btn, 1, wxGROW | wxALL, 2)
btn = wxButton(self, 1204, "Back")
EVT_BUTTON(self, 1204, self.OnBack)
subbox.Add(btn, 1, wxGROW | wxALL, 2)
btn = wxButton(self, 1205, "Forward")
EVT_BUTTON(self, 1205, self.OnForward)
subbox.Add(btn, 1, wxGROW | wxALL, 2)
self.box.Add(subbox, 0, wxGROW)
self.SetSizer(self.box)
self.SetAutoLayout(true)
def OnLoadPage(self, event):
dlg = wxTextEntryDialog(self, 'Location:')
if dlg.ShowModal() == wxID_OK:
self.destination = dlg.GetValue()
dlg.Destroy()
self.html.LoadPage(self.destination)
def OnLoadFile(self, event):
dlg = wxFileDialog(self, wildcard = '*.htm*', style=wxOPEN)
if dlg.ShowModal():
path = dlg.GetPath()
self.html.LoadPage(path)
dlg.Destroy()
def OnBack(self, event):
if not self.html.HistoryBack():
wxMessageBox("No more items in history!")
def OnForward(self, event):
if not self.html.HistoryForward():
wxMessageBox("No more items in history!")
Assuming you've been playing along in your Python interpreter as you read this, you may have noticed that the application never returns control back to the console if you close it. This is a simple thing to fix, but maybe we should add a menu bar to provide a file menu with an exit option:
Listing 4. Modifying exFrame to add file menu with exit
class exFrame(wxFrame):While we're off trying to turn this into a real browser, there are a couple of finishing touches that we're missing: most browsers have a status bar, and you may have noticed that no images are being drawn. The following modifications to exApp, exFrame, and exHtmlPanel add a status bar and all built-in image support from wxPython:
def __init__(self, parent, ID, title):
wxFrame.__init__(self, parent, ID, title, wxDefaultPosition, wxSize(600,750))
panel = exHtmlPanel (self, -1, self)
mnu_file = wxMenu()
mnu_file.Append(101, "E&xit", "Exit the browser")
menuBar = wxMenuBar()
menuBar.Append(mnu_file, "F&ile")
self.SetMenuBar(menuBar)
EVT_MENU(self, 101, self.Exit)
def Exit(self, event):
self.Close(true)
Listing 5. Adding a status bar and image support
class exApp(wxApp):Now your basic browser should be fully functional. Advanced features of wxPython allow you to create your own tags that are handled by custom code to do any action of your choice. Having control of your own customizable embedded browser provides an endless array of possibilities for enhanced reporting and online help.
def OnInit(self):
+ wxInitAllImageHandlers()
frame = exFrame(NULL, -1, "Example Browser")
frame.Show(true)
self.SetTopWindow(frame)
return true
class exHtmlPanel(wxPanel):
def __init__(self, parent, id, frame):
wxPanel.__init__(self, parent, -1)
self.frame = frame
self.cwd = os.path.split(sys.argv[0])[0]
if not self.cwd:
self.cwd = os.getcwd
self.html = exHtmlWindow(self, -1, self.frame)
+ self.html.SetRelatedFrame(self.frame, "%s")
+ self.html.SetRelatedStatusBar(0)
...
class exFrame(wxFrame):
def __init__(self, parent, ID, title):
wxFrame.__init__(self, parent, ID, title, wxDefaultPosition, wxSize(600,750))
panel = exHtmlPanel (self, -1, self)
+ self.CreateStatusBar()
+ self.SetStatusText("Default status bar")
...
This code could easily provide the foundation for any number of apps entirely on its own, as well -- there is no reason to limit yourself just to providing online help. Feel free to play around with these classes and see what interesting behavior you can whip up. :-)
Tutorial Pages:
» Building Basic Browser Functionality with wxPython
» The World's Most Basic Browser
» Resources
First published by IBM DeveloperWorks
