Tuesday, April 24, 2012

Making GtkWebKit Inspector and enable-developer-extras actually work in Python


I have become quite fascinated by using HTML5 for rendering my GUIs on my Ubuntu applications. I love doing this, because I can continue to use Python as my library and desktop integration point, while being free to use cutting edge presentation technology.

I sat down with didrocks yesterday and we set off to create a simple Quickly template out of some of the code I've written for bootstrapping these projects. The template will be very very simple. All it will do is set up communication between HTML and Javascript in an GtkWebKit window, and a Python back end. Developers will be free to choose how to use the WebKit window. For example, they could use JQuery or a host of other javascript libraries if they chose.

Didrocks was adamant that we should expose the excellent debugger (called The Inspector) that comes with WebKit in the template. However, I have found that for GtkWebKit, the doucmentation is sketchy (at best), and the API is unpredictable in it's behavior. So, it took us 2 hours of experimentation and trolling source code to make an implementation that actually worked for showing The Inspector.

So, if you have been trolling the web looking for how to make this work .. I hope this works for you! Without further ado, here is a commented minimial example of a WebKit window that shows the Inspector. I also pushed a branch with just the code in case you find that easier to read or work with.
 from gi.repository import WebKit  
 from gi.repository import Gtk  
 import os  
 #The activate_inspector function gets called when the user  
 #activates the inspector. The splitter is a Gtk.Splitter and is user  
 #data that I passed in when I connected the signals below.  
 #The important work to be done is to create a new WebView  
 #and return it in the function. WebKit will use this new View  
 #for displaying The Inspector. Along the way, we need to add  
 # the view to the splitter  
 def activate_inspector(inspector, target_view, splitter):  
   inspector_view = WebKit.WebView()  
   splitter.add2(inspector_view)  
   return inspector_view  
 #create the container widgets  
 window = Gtk.Window()  
 window.set_size_request(400,300)  
 window.connect("destroy",Gtk.main_quit)  
 splitter = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)  
 window.add(splitter)  
 #create the WebView  
 view = WebKit.WebView()  
 #Use set_property to turn on enable-developer-extras. This will  
 #cause "Inspect Element" to be added to the WebKit's context menu.  
 #Do not use view.get_settings().enable_developer_extras = True,   
 #this does not work. Only using "set_property" works.  
 view.get_settings().set_property("enable-developer-extras",True)  
 #Get the inspector and wire the activate_inspector function.  
 #Pass the splitter as user data so the callback function has  
 #a place to add the Inspector to the GUI.  
 inspector = view.get_inspector()  
 inspector.connect("inspect-web-view",activate_inspector, splitter)  
 #make a scroller pane to host the main WebView  
 sw = Gtk.ScrolledWindow()   
 sw.add(view)   
 splitter.add1(sw)  
 #put something in the WebView  
 html_string = "<HTML><HEAD></HEAD><BODY>Hello World</BODY></HTML>"  
 root_web_dir = os.path.dirname(os.path.dirname(__file__))  
 root_web_dir = "file://%s/" % root_web_dir  
 view.load_html_string(html_string, root_web_dir)  
 #show the window and run the program  
 window.show_all()  
 Gtk.main()  

7 comments:

  1. Hey Rick!

    I'm not as great a fan of HTML as a GUI language as you are, but I do see some of the benefits. One thing that annoys me with HTML applications is that you have to use JavaScript. On the web, that's understandable, but for local applications that just want to use HTML as an interface definition, it doesn't. So I've been thinking about playing with it in Python and Vala to see if I can do something fascinating.

    There seems to be a lack of tutorials in this area. Do you know of any, or know any good example applications with simple code that can illustrate the concepts?

    Jo-Erlend

    ReplyDelete
  2. That's exactly what I was looking for.
    [ C'est exactement ce que je cherchais ]
    Thanks Rick.

    ReplyDelete
  3. Thanks! This was exactly what I needed. I didn't go to the work of setting up the splitter. All I needed was:

    browser.get_settings().set_property("enable-developer-extras",True)

    inspector = Inspector(browser.get_web_inspector())

    The set_property was the key. Thanks!

    ReplyDelete
  4. Awesome! Great work. I am really excited to give this a try.

    ReplyDelete
  5. Nice! I wondered how to set the inspector to be a dock. Unfortunately it seems to have problems with resizing. Also, the middle breadcrumb-resizer bar doesn't come up when you click the "console" button (second at bottom left), and the scrollbars have no up/down arrows. Anyone know a solution for this?

    ReplyDelete
    Replies
    1. It seems this bug has still not been fixed in 12.10. It's not just in Python+GTK+Webkit, Midori also has a broken slider/breadcrumb. I've described the problem in depth here:

      http://stackoverflow.com/questions/13132459/webkit-browsers-inspector-is-missing-a-few-things

      Delete
    2. The bug persists in 13.04 beta as well.

      Delete