WebKit WebView फ़ॉर्म को पायथन कॉलबैक से कनेक्ट करें?


31

मैं एक छोटा सा पायथन और वेबकीट ऐप लिख रहा हूं; मैं अपने ऐप के लिए UI के रूप में WebKit का उपयोग कर रहा हूं।

मैं क्या करना चाहता हूं वेबकेइट में एक इंटरैक्टिव तत्व (अर्थात् एक कॉम्बो बॉक्स या क्लिक करने योग्य क्षेत्रों का एक सेट) बनाने के लिए और जब उपयोगकर्ता इन तत्वों के साथ बातचीत करता है तो मैं कुछ प्रसंस्करण करने के लिए पायथन कॉलबैक को कॉल कर सकता हूं और फिर वेबिट दृश्य के साथ अद्यतन कर सकता हूं नई जानकारी।

यहाँ एक उदाहरण है कि मैं क्या करना चाहता हूँ:

  1. उपयोगकर्ता विकल्पों के कॉम्बो बॉक्स के साथ प्रस्तुत किया गया है (कॉम्बो बॉक्स प्रदर्शित किया गया है, मुझे लगता है, WebKit में HTML फॉर्म का उपयोग करके)।
  2. जब कॉम्बो बॉक्स विकल्प का चयन किया on_combo_selected()जाता है , तो इसे मेरे पाइथन स्क्रिप्ट में कहा जाता है जो तब कुछ डेटा को पकड़ लेता है।
  3. डेटा को WebKit को पास कर दिया जाता है और व्यू अपडेट किया जाता है।

मैं यह कैसे कर सकता हूँ?

जवाबों:


31

पाइथन कार्यक्रम को नियंत्रित करने के लिए एक एम्बेडेड WebKit विजेट से संवाद करने के तरीके

Gtk या Qt:

  • window.statusजावास्क्रिप्ट से सेट ; पायथन में इसी घटना को फँसाना
  • document.titleजावास्क्रिप्ट से सेट ; पायथन में इसी घटना को फँसाना
  • पृष्ठ को एक कस्टम URL पर पुनर्निर्देशित करें (कहें, x-my-app:thing1/thing2/thing3); navigation-policy-decision-requestedपायथन में ट्रैप ईवेंट और उस URL को देखें, जिसे आपके कस्टम URL स्कीम के लिए नेविगेट किया जा रहा है और उससे निपटें

केवल क्यूटी:

  • frame.addToJavaScriptWindowObjectजावास्क्रिप्ट वैश्विक नाम स्थान पर पायथन ऑब्जेक्ट (विशेष रूप से डिज़ाइन) को जोड़ने के लिए उपयोग ; जावास्क्रिप्ट से उस पर कॉल के तरीके। ( उदाहरण के लिए http://pysnippet.blogspot.com/2010/01/calling-python-from-javascript-in-pyqts.html देखें ।)

वे तरीके जो सैद्धांतिक रूप से काम करने चाहिए लेकिन व्यवहार में बहुत अच्छे नहीं हैं

  • जावास्क्रिप्ट से एक HTML तत्व (जिसमें दस्तावेज़ ऑब्जेक्ट शामिल होगा) पर एक कस्टम डोम घटना को आग देना; पायथन से WebKit DOM नेविगेट करके और घटनाओं के लिए सुनकर पायथन में उस घटना का जाल। यह काम करता है, लेकिन मैं इवेंट से कस्टम डेटा पढ़ने में सक्षम होने का एक तरीका नहीं खोज सकता, जिसका अर्थ है कि आप फायर किए जाने वाले इवेंट के अलावा अन्य जानकारी पास नहीं कर सकते।

पाइथन से जावास्क्रिप्ट तक संवाद करने के तरीके

  • उपयोग करें webview.execute_script(js_code)। ध्यान दें कि यदि आप JS के साथ वैरिएबल वैल्यू पास कर रहे हैं, तो JSON के लिए यह एक अच्छा विचार है; इस तरह आप भागने के बारे में थोड़ा कम चिंता कर सकते हैं, और जेएस जेन्सन को मूल रूप से पढ़ सकते हैं

यहाँ कुछ उदाहरण 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()

18

जब से मैं उसके साथ खेला था, तब से कुछ समय हो गया है, लेकिन यहाँ मैंने क्या किया है:

जैसे कुछ का उपयोग करें

<form>
    <select  onchange="location.href='mycombo://'+this.value">
      <option>foo</option>
      <option>bar</option>
      <option>baz</option>
    </select>
</form>

अपने HTML में इसलिए जब उपयोगकर्ता किसी वस्तु का चयन करता है mycombo-URI चयनित मूल्य के साथ कहा जाता है। इसे पकड़ने के लिए अपने WebView navigation-requestedसिग्नल को हैंडलर से कनेक्ट करें :

self.webview.connect("navigation-requested", self.on_navigation_requested)

आपके सिग्नल हैंडलर में आप जांचते हैं कि अनुरोध mycomboURI के लिए है या नहीं । यदि ऐसा है तो कॉल करें on_combo_selected:

def on_navigation_requested(self, view, frame, req, data=None):
    uri = req.get_uri()
    scheme, path=uri.split(':', 1)
    if scheme == 'mycombo':
        self.on_combo_selected(path) 
        return True
    else:
        return False

अपने WebView को अपडेट execute_scriptकरने के लिए कुछ जावास्क्रिप्ट कोड चलाने के लिए अपने फ़ंक्शन का उपयोग करें जो अपडेट करता है, जैसे:

self.webview.execute_script("document.title='Updated!';")

1
किसी भी विचार कैसे पोस्ट हेडर से प्राप्त करने के लिए req?
फ़्लिम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.