Formas de comunicação de um widget incorporado do WebKit para o programa Python de controle
Gtk ou Qt:
- defina
window.status
do JavaScript; interceptar o evento correspondente no Python - defina
document.title
do JavaScript; interceptar o evento correspondente no Python - redirecionar a página para um URL personalizado (digamos,
x-my-app:thing1/thing2/thing3
); trapnavigation-policy-decision-requested
event no Python, observe o URL que está sendo navegado e lide com ele se for seu esquema de URL personalizado
Somente Qt:
- use
frame.addToJavaScriptWindowObject
para adicionar um objeto Python (projetado especificamente) ao namespace global JavaScript; chame métodos nele de JavaScript. (Veja link para um exemplo.)
Métodos que teoricamente deveriam funcionar, mas na prática não, muito bem
- Dispara um evento DOM personalizado em um elemento HTML (que incluiria o objeto do documento) do JavaScript; interceptar esse evento no Python, navegando no WebKit DOM do Python e ouvindo os eventos. Isso funciona, mas não consigo encontrar uma maneira de o Python conseguir ler dados personalizados do evento, o que significa que você não pode passar informações além do evento que foi acionado.
Formas de comunicação do Python para JavaScript
- use
webview.execute_script(js_code)
. Observe que, se você passar valores de variável com o JS, é uma boa ideia codificá-los no JSON. Dessa forma, você pode se preocupar um pouco menos com o escape, e o JS pode ler JSON nativamente
Veja alguns exemplos de código Gtk:
from gi.repository import Gtk,WebKit
import json
w = Gtk.Window()
v = WebKit.WebView()
sw = Gtk.ScrolledWindow()
w.add(sw)
sw.add(v)
w.set_size_request(400,300)
w.connect("destroy", lambda q: Gtk.main_quit())
def window_title_change(v, param):
if not v.get_title():
return
if v.get_title().startswith("msgtopython:::"):
message = v.get_title().split(":::",1)[1]
# Now, send a message back to JavaScript
return_message = "You chose '%s'. How interesting." % message
v.execute_script("jscallback(%s)" % json.dumps(return_message))
v.connect("notify::title", window_title_change)
v.load_html_string("""<!doctype html>
<html>
<head>
<title>A demo</title>
<style>
body { font-family: Ubuntu, sans-serif; }
h1 { font-size: 1.3em; }
</style>
<body>
<h1>A tiny JavaScript demonstration</h1>
<form>
<p>What's your favourite thing about Jono? <select>
<option>------choose one------</option>
<option>his beard</option>
<option>his infectious sense of humour</option>
<option>his infectious diseases</option>
<option>his guitar ability</option>
<option>his wife</option>
</select></p>
</form>
<p id="out"></p>
<script>
document.querySelector("select").addEventListener("change", function() {
var chosenOption = this.options[this.selectedIndex].text;
// Now send that text back to Python by setting the title
document.title = "msgtopython:::" + chosenOption;
}, false);
function jscallback(msg) {
document.getElementById("out").innerHTML = msg;
}
</script>
</body>
</html>
""", "file:///")
w.show_all()
Gtk.main()