Problem with wx.html2.webview and a zip file

I hit a wall and am completely clueless.

Relevant code:

url = “wxzip://help.zip;protocol=zip/quickguide.html”

self.m_htmlWin = wx.html2.WebView.New(self, size = wx.Size(900,500))
self.m_htmlWin.RegisterHandler(wx.html2.WebViewArchiveHandler(“wxzip”))
self.m_htmlWin.LoadURL(url)

I get the error message “File not found: wxzip://help.zip;protocol=zip/quickguide.html”

The problem is that the file does exist (confirmed with a call to os.path.isfile(“help.zip”), in case something went amiss in the code), it does contain a “quickguide.html” inside, and to make things worse, when I submit that same url to the wxPython WebView demo program, it shows without a problem.

I ran out of ideas, if anyone has a hint, I’ll be glad…

I think it’s something to do with the SetupMemoryFiles() function in the webview_sample.py program.

If I comment out the call to that function in the main() function, then clicking on the zip-file link produces the “File not found” error.

Conversely, if I add the SetupMemoryFiles() function and the necessary constants to my simple example, then it works OK.

import os
import wx
import wx.html2 as webview

HERE = os.path.abspath(os.path.dirname(__file__))
BASE = 'file://{}/'.format(HERE.replace('\\', '/'))
URL = BASE + 'webview_sample.html'
LOGO = os.path.join(HERE, 'logo.png')

# We need to be in the HERE folder for the archive link to work since the sample
# page does not use a full path
os.chdir(HERE)

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((800, 800))
        self.SetTitle("Zip Archive")
        self.main_panel = wx.Panel(self, wx.ID_ANY)
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        self.wv = webview.WebView.New(self.main_panel)
        main_sizer.Add(self.wv, 1, wx.EXPAND, 0)
        self.main_panel.SetSizer(main_sizer)
        self.Layout()

        # This handler takes care of links that are in zip files
        self.wv.RegisterHandler(webview.WebViewArchiveHandler("wxzip"))

        self.wv.LoadURL("wxzip://simpleweb.zip;protocol=zip/index.html")
        # self.wv.LoadURL("file:///home/richardt/Development/python/exp/hci/wxpython/web_view/zip_files/webview_sample.html")


def SetupMemoryFiles():
    # Set up an in-memory file system with virtual "files" that can be
    # loaded into the webview just like network or local file sources.
    # These "files" can be access using a protocol specifier of "memory:"
    wx.FileSystem.AddHandler(wx.MemoryFSHandler())
    wx.FileSystem.AddHandler(wx.ArchiveFSHandler())
    wx.MemoryFSHandler.AddFile(
        "page1.html",
        "<html><head><title>File System Example</title>"
        "<link rel='stylesheet' type='text/css' href='memory:test.css'>"
        "</head><body><h1>Page 1</h1>"
        "<p><img src='memory:logo.png'></p>"
        "<p>This file was loaded directly from a virtual in-memory filesystem.</p>"
        "<p>Here's another page: <a href='memory:page2.html'>Page 2</a>.</p></body>")
    wx.MemoryFSHandler.AddFile(
        "page2.html",
        "<html><head><title>File System Example</title>"
        "<link rel='stylesheet' type='text/css' href='memory:test.css'>"
        "</head><body><h1>Page 2</h1>"
        "<p><a href='memory:page1.html'>Page 1</a> was better.</p></body>")
    wx.MemoryFSHandler.AddFile(
        "test.css",
        "h1 {color: red;}")
    wx.MemoryFSHandler.AddFile('logo.png', wx.Bitmap(LOGO), wx.BITMAP_TYPE_PNG)


if __name__ == "__main__":
    app = wx.App()
    SetupMemoryFiles()
    frame = MyFrame(None)
    frame.Show()
    app.MainLoop()

This needs the simpleweb.zip and logo.png files from the demo’s samples/html2 directory.

Tested using Python 3.10.12 + wxPython 4.2.1 gtk3 (phoenix) wxWidgets 3.2.2.1 on Linux Mint 21.2

It looks like if you are just wanting to support zip files you just need to call:

wx.FileSystem.AddHandler(wx.ArchiveFSHandler())

e.g.

import wx
import wx.html2 as webview

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((800, 800))
        self.SetTitle("Zip Archive")
        self.main_panel = wx.Panel(self, wx.ID_ANY)
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        self.wv = webview.WebView.New(self.main_panel)
        main_sizer.Add(self.wv, 1, wx.EXPAND, 0)
        self.main_panel.SetSizer(main_sizer)
        self.Layout()

        # This handler takes care of links that are in zip files
        self.wv.RegisterHandler(webview.WebViewArchiveHandler("wxzip"))

        self.wv.LoadURL("wxzip://simpleweb.zip;protocol=zip/index.html")

if __name__ == "__main__":
    app = wx.App()
    wx.FileSystem.AddHandler(wx.ArchiveFSHandler())
    frame = MyFrame(None)
    frame.Show()
    app.MainLoop()

Bingo! That did the trick, can’t thank you enough, man!