Dies ist eine alte Frage, aber ...
Um PyQt Funktionen von Javascript ausführen:
Während dies zu tun, zahlreiche Möglichkeiten sein kann, habe ich es gelöst, indem QWebChannel
verwenden, und dann Rufen Sie js Funktionen von Ihrem HTML auf, als dann verwenden Sie den Web-Kanal, um mit Qt zu kommunizieren.
Sie benötigen qwebchannel.js
. Ich habe meinen aus dem Qt5-Beispielverzeichnis auf meinem lokalen Rechner. Die gleiche Datei existiert an vielen Stellen im Internet. Ich überlasse es dir, es zu finden.
Ein großer Teil dieser Methode ist hier beschrieben: http://doc.qt.io/qt-5/qtwebchannel-javascript.html
In Ihrem __init__
, einen Web-Kanal erstellen:
self.webchannel = QtWebChannel.QWebChannel(self)
setzen dann Haupt-Seite Ihres webengineview den Kanal zu verwenden, und registrieren Sie das gewünschte Objekt geteilt zwischen PyQt und js werden:
self.page().setWebChannel(self.webchannel)
self.webchannel.registerObject('MyChannel', self)
In Ihrem Js (oder die JavaScript-Abschnitt Ihrer .html), Einrichtung der Web-c hannel:
var MyChannel = null;
new QWebChannel(qt.webChannelTransport, function(channel) {
MyChannel = channel.objects.MyChannel;
});
(Dies ist, wo qwebchannel.js
ins Spiel kommt. Ihre js oder html Datei muss es enthalten können. Für mich habe ich geladen <script src="scripts/qwebchannel.js"></script>
bevor Sie eine andere js
Jetzt sind Sie eingerichtet, Anrufe von js zu PyQt über den Kanal zu machen, aber was können Sie anrufen? Alles, was als PyQt-Slot eingerichtet ist. So zum Beispiel, wenn in Javascript, Sie ein „foo“ -Funktion in Render, dass nimmt einen String als Argument nennen wollte, dann würden Sie es schaffen (als Mitglied der Render) als solche:
@QtCore.pyqtSlot(str)
def foo(self, some_tring):
print ("Some string: %s" % game_data)
... und dann in der js-Datei (oder in Ihrer index.html), würden Sie einfach einen Anruf an MyChannel.foo('whatever')
. Sie können dies als onclick tun, oder Sie können es aus dem Körper einer anderen Funktion tun, die Sie von onclick aufrufen.
Gespräch durch MyChannel.foo('whatever')
: Sie MyChannel
nennen, weil, dass der Name, den Sie das Objekt, das Sie mit dem Kanal (in Python) registrieren zugewiesen waren, und der Namen, den Sie in js verwendet, wenn Sie die new QWebChannel
erstellt. Wenn Sie die Registrierung erstellt haben, haben Sie self
als zu registrierendes Objekt übergeben. Der durch MyChannel
identifizierte Kanal ist also Ihr Render
Objekt. Sie können nur über den Kanal signalisieren, also muss alles, was Sie anrufen, ein Slot sein - daher der Dekorateur.
Alternativ, wenn Sie eine js-Funktion von PyQt aufrufen möchten, ist es ein bisschen einfacher. In diesem Fall rufen Sie einfach
self.page().runJavaScript('someJsFunction("whatever");')
Wenn Sie etwas mit der Antwort, das zu tun brauchen, weil es async genannt wird, Sie eine Antwort-Handler-Setup benötigen:
self.page().runJavaScript('someJsFunction("whatever");', self.__callback)
.. .und dann den Callback definieren (wahrscheinlich als Mitglied von Render):
def __callback(self, response):
if response:
print ("Handling JS response: %s", response)