Search code examples
pythongtkwebkit

How do I load an image into a WebKit browser?


The task is to implement a webkit browser that can open any files. At the moment, I managed to implement only the opening of html.

#!/usr/bin/env python3

import os
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('WebKit2', '4.0')
from gi.repository import Gtk, WebKit2


def on_click(button):
    chooser = Gtk.FileChooserDialog(
        title="Open File", action=Gtk.FileChooserAction.OPEN
    )
    chooser.add_buttons(
        Gtk.STOCK_CANCEL,
        Gtk.ResponseType.CANCEL,
        Gtk.STOCK_OPEN,
        Gtk.ResponseType.OK,
    )
    chooser.set_default_response(Gtk.ResponseType.OK)
    if chooser.run() == Gtk.ResponseType.OK:
        filename = chooser.get_filename()
        chooser.destroy()
        f = open(filename)
        name, ext = os.path.splitext(filename)
        if ext == '.html':
            webview.load_html(f.read())
    else:
        chooser.destroy()


win = Gtk.Window()
win.connect("destroy", Gtk.main_quit)
win.set_border_width(10)
win.set_default_size(400, 200)

hb = Gtk.HeaderBar()
hb.set_show_close_button(True)
hb.props.title = "Browser"
win.set_titlebar(hb)

box = Gtk.HBox()
button = Gtk.Button(label="Open file")
button.connect("clicked", on_click)
box.add(button)
hb.pack_start(box)

webview = WebKit2.WebView()
win.add(webview)
win.show_all()
Gtk.main()

And there was an attempt to implement the opening of images

#!/usr/bin/env python3

import os
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('WebKit2', '4.0')
from gi.repository import Gtk, WebKit2


def on_click(button):
    chooser = Gtk.FileChooserDialog(
        title="Open File", action=Gtk.FileChooserAction.OPEN
    )
    chooser.add_buttons(
        Gtk.STOCK_CANCEL,
        Gtk.ResponseType.CANCEL,
        Gtk.STOCK_OPEN,
        Gtk.ResponseType.OK,
    )
    chooser.set_default_response(Gtk.ResponseType.OK)
    if chooser.run() == Gtk.ResponseType.OK:
        filename = chooser.get_filename()
        chooser.destroy()
        f = open(filename)
        name, ext = os.path.splitext(filename)
        pic_types = (
            '.jpg', '.jpeg', '.jfif', '.pjpeg', '.pjp',
            '.png', '.swg', '.webp'
            )


        image = Gtk.Image()
        image.set_from_file(filename)
        image.set_halign(Gtk.Align.START)
        image.set_valign(Gtk.Align.START)
        overlay.add_overlay(image)
        win.add(overlay)

    else:
        chooser.destroy()


win = Gtk.Window()
win.connect("destroy", Gtk.main_quit)
win.set_border_width(10)
win.set_default_size(400, 200)

hb = Gtk.HeaderBar()
hb.set_show_close_button(True)
hb.props.title = "Browser"
win.set_titlebar(hb)

box = Gtk.HBox()
button = Gtk.Button(label="Open file")
button.connect("clicked", on_click)
box.add(button)
hb.pack_start(box)

webview = WebKit2.WebView()
overlay = Gtk.Overlay()
overlay.add(webview)

win.show_all()
Gtk.main()

Images are not opening, what could be the reason? How to open files of any extensions? Perhaps this can be done if you use a file placed in the html tags of the page?


Solution

  • You can use webview.load_uri() to load any type of file, and the WebView itself will worry about how to display it.

    Hence, on_click() shoud look like this:

    def on_click(button):
        chooser = Gtk.FileChooserDialog(
            title="Open File", action=Gtk.FileChooserAction.OPEN
        )
        chooser.add_buttons(
            Gtk.STOCK_CANCEL,
            Gtk.ResponseType.CANCEL,
            Gtk.STOCK_OPEN,
            Gtk.ResponseType.OK,
        )
        chooser.set_default_response(Gtk.ResponseType.OK)
        if chooser.run() == Gtk.ResponseType.OK:
            filename = chooser.get_filename()
            chooser.destroy()
    
            # Use load_uri()
            webview.load_uri("file://" + filename)
    
        else:
            chooser.destroy()
    

    Note that you have to use "file://" + filename, because that's how browsers know that you're opening a local file. It works the same way as https:// in that it tells the browser what to do with the link; https:// tells the browser that the path is on the web.

    If you're on a Windows, you might need to replace each / with \\, but I can't be sure, since I'm not on Windows.