簡體   English   中英

使用QWebEngineView與html / javascript進行通信

[英]Communicate with html/javascript using QWebEngineView

我需要獲取一個動態內容,該內容由ajax js調用加載。

我真的不知道如何使用PyQt,但我希望可以做到這一點。 HTML類似於:

<a href="#" id="id" onclick="A4J.AJAX.Submit('j_id0:j_id1:j_id110',event,{'similarityGroupingId':'j_id0:j_id1:j_id110:j_id582:0:j_id584'});return false;">NETHERLANDS</a>`

我可以使用以下簡單代碼使用PyQt渲染頁面:

def render(source_html):

    import sys
    from PyQt5.QtCore import QEventLoop
    from PyQt5.QtWidgets import QApplication
    from PyQt5.QtWebEngineWidgets import QWebEngineView

    class Render(QWebEngineView):
        def __init__(self, html):
            self.html = None
            self.app = QApplication(sys.argv)
            QWebEngineView.__init__(self)
            self.loadFinished.connect(self._loadFinished)
            self.setHtml(html)

            while self.html is None:
                self.app.processEvents(QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers | QEventLoop.WaitForMoreEvents)
            self.app.quit()

        def _callable(self, data):
            self.html = data

        def _loadFinished(self, result):
            self.page().toHtml(self._callable)

    return Render(source_html).html

import requests
sample_html = requests.get('https://riverbankcomputing.com/software/pyqt/').text
print(render(sample_html))

如何運行“ onclick”並獲取內容?

這是一個老問題,但是...

要從javascript運行PyQt函數:

盡管可能有很多方法可以實現,但是我已經通過使用QWebChannel解決了它,然后從您的html調用js函數,然后使用Web通道與Qt進行通信。

您將需要qwebchannel.js 我是從本地計算機上的Qt5示例目錄獲得的。 網路上的許多地方都有相同的檔案。 我讓你找它。

此處介紹了許多這種方法: http : //doc.qt.io/qt-5/qtwebchannel-javascript.html

__init__ ,創建一個網絡渠道:

self.webchannel = QtWebChannel.QWebChannel(self)

然后將您的webengineview的主頁設置為使用該頻道,並注冊要在PyQt和js之間共享的對象:

self.page().setWebChannel(self.webchannel)
self.webchannel.registerObject('MyChannel', self)

在您的.js(或.html的javascript部分)中,設置網絡渠道:

var MyChannel = null;
new QWebChannel(qt.webChannelTransport, function(channel) {
                MyChannel = channel.objects.MyChannel;
});

(這是qwebchannel.js發揮作用的地方。您的js或html文件必須能夠包含它。對我來說,我在執行其他任何js之前先加載<script src="scripts/qwebchannel.js"></script>

現在,您已設置為通過通道從js調用PyQt,但是您可以調用什么呢? 任何裝飾為PyQt插槽的東西。 因此,例如,如果您想在javascript中調用Render中的“ foo”函數,該函數將字符串作為參數,則可以這樣創建它(作為Render的成員):

@QtCore.pyqtSlot(str)
def foo(self, some_tring):
    print ("Some string: %s" % some_string)

...然后在js文件中(或在index.html中),只需調用MyChannel.foo('whatever') 您可以將其作為onclick進行,也可以從onclick調用的另一個函數的主體中進行。

通過MyChannel.foo('whatever')交談:之所以調用MyChannel ,是因為這是分配給在通道中注冊的對象的名稱(在python中),也是在創建new QWebChannel時在js中使用的名稱。 創建注冊時,您將self作為要注冊的對象傳遞-因此,由MyChannel標識的通道是您的Render對象。 您只能通過通道發出信號,因此您“呼叫”的任何內容都必須是插槽-因此是裝飾器。


另外,如果您想從PyQt調用js函數,則要容易一些。 在這種情況下,您只需致電

self.page().runJavaScript('someJsFunction("whatever");')

如果您需要對響應做出某種處理,因為它被稱為異步,則需要設置響應處理程序:

self.page().runJavaScript('someJsFunction("whatever");', self.__callback)

...然后定義回調(可能是Render的成員):

def __callback(self, response):
    if response:
        print ("Handling JS response: %s", response)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM