[英]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.