2017-01-26 11 views
3

Мне нужно получить динамический контент, загружаемый вызовом ajax js.получить динамический контент с помощью PyQt

Я действительно не знаю, как использовать 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» и получить содержание?

ответ

1

Это старый вопрос, но ...

Для запуска функции PyQt из JavaScript:

Хотя может быть множество способов сделать это, я решил его с помощью QWebChannel, а затем вызывая функции js из вашего html, а затем используйте веб-канал для связи с Qt.

Вам понадобится qwebchannel.js. Я получил мой из каталога примеров Qt5 на моей локальной машине. Один и тот же файл существует в Интернете во многих местах. Я оставлю это вам, чтобы найти его.

Большая часть этого метода описана здесь: http://doc.qt.io/qt-5/qtwebchannel-javascript.html

В вашем __init__, создать веб-канал:

self.webchannel = QtWebChannel.QWebChannel(self) 

установите главную страницу вашего webengineview, чтобы использовать канал, и зарегистрировать объект, который вы хотите быть разделен между PyQt и ЯШАМИ:

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

в вашем .js (или яваскрипт раздел вашего .html), настройка веб-с hannel:

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

(Это где qwebchannel.js вступает в игру. Ваш js или html-файл должен иметь возможность включить его. Для меня я загрузил <script src="scripts/qwebchannel.js"></script> перед выполнением каких-либо других js

Теперь вы настраиваете вызовы от js до PyQt по каналу, но что вы можете назвать? Все, что украшено слотом PyQt. Так, например, если в JavaScript, вы хотите вызвать функцию «Foo» в визуализации, которая принимает строку в качестве аргумента, то вы можете создать его (как член Рендер) как таковой:

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

... а затем в файле js (или в вашем index.html), вы просто позвоните MyChannel.foo('whatever'). Вы можете сделать это как onclick, или вы можете сделать это из тела другой функции, которую вы вызываете из onclick.

Разговор через MyChannel.foo('whatever'): Вы называете MyChannel, потому что это было имя, назначенное к объекту, зарегистрированному в канале (в Python), и имя, которое вы использовали в JS при создании new QWebChannel. Когда вы создали регистрацию, вы передали self в качестве объекта для регистрации - поэтому канал, идентифицированный MyChannel, является вашим Render объектом. Вы можете сигнализировать только по каналу, поэтому все, что вы вызываете, должно быть слотом - отсюда и декоратор.


В качестве альтернативы, если вы хотите вызвать функцию js из PyQt, это немного проще. В этом случае, вы просто звоните

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)