This code is just an example using Google site, but I want it work for any JavaScript-enabled sites. So, I have: QPushButton object which is connected to getAnswer function which take text entered to QLineEdit object and (should) pass it to QThread, where this text should be used in search(text) function. Afterwards resulting text should appear in QLabel object. The question is: how do I pass this string to QThread and resulting string out? The code below is expectedly crashed on
Qt Code:
  1. self.get_thread = getGoogle(self.text)
To copy to clipboard, switch view to plain text mode 
which is wrong.
Qt Code:
  1. #!/usr/bin/python3
  2. # -*- coding: utf-8 -*-
  3.  
  4. import sys
  5. from bs4 import BeautifulSoup
  6. from PyQt5.QtWidgets import QApplication, QWidget, \
  7. from PyQt5.QtCore import pyqtSignal, QEventLoop, QThread
  8. from PyQt5.QtWebEngineWidgets import QWebEngineView
  9. from requests import get
  10.  
  11.  
  12. class getGoogle(QThread):
  13. def __init__(self):
  14. QThread.__init__(self)
  15. self.text=text
  16.  
  17. def __del__(self):
  18. self.wait()
  19.  
  20. def render(source_html):
  21. class Render(QWebEngineView):
  22. def __init__(self, html):
  23. self.html = None
  24. self.app = QApplication([])
  25. QWebEngineView.__init__(self)
  26. self.loadFinished.connect(self._loadFinished)
  27. self.setHtml(html)
  28. while self.html is None:
  29. self.app.processEvents(QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers | QEventLoop.WaitForMoreEvents)
  30. self.app.quit()
  31.  
  32. def _callable(self, data):
  33. self.html = data
  34.  
  35. def _loadFinished(self):
  36. self.page().toHtml(self._callable)
  37.  
  38. return Render(source_html).html
  39.  
  40. def search(self, text):
  41. query=str(text)
  42. query = query.replace(" ", "+")
  43. url='https://www.google.com/search?q=' + query
  44. headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
  45. sample_html = get(url, headers=headers).text
  46. soup = BeautifulSoup(self.render(sample_html), "html.parser")
  47. res = soup.find('span', attrs={'class': 'cwcot'})
  48. res = res.get_text()
  49. return res
  50.  
  51. def run(self):
  52. result=self.search(text)
  53. self.emit(pyqtSignal('add_answer(QString)'), result)
  54. self.sleep(2)
  55.  
  56.  
  57. class MyApp(QWidget):
  58. def __init__(self):
  59. super().__init__()
  60. self.initUI()
  61.  
  62. def initUI(self):
  63. self.sendButton = QPushButton('Ask', self)
  64. self.questionEdit = QLineEdit(self)
  65. self.answer=QLabel(self)
  66. grid = QGridLayout(self)
  67. grid.setSpacing(10)
  68. grid.addWidget(self.questionEdit, 1, 0)
  69. grid.addWidget(self.sendButton, 1, 1)
  70. grid.addWidget(self.answer, 2,0)
  71. self.sendButton.clicked.connect(self.getAnswer)
  72. self.setLayout(grid)
  73. self.resize(500, 100)
  74. self.show()
  75.  
  76. def getAnswer(self):
  77. text = self.questionEdit.text()
  78. if len(text)>=1:
  79. self.get_thread = getGoogle(self.text)
  80. self.connect(self.get_thread, pyqtSignal("add_answer(QString)"), self.answer.setText)
  81. self.get_thread.start()
  82. else:
  83. self.answer.setText("Specify your question")
  84.  
  85. if __name__ == '__main__':
  86. app = QApplication(sys.argv)
  87. my = MyApp()
  88. sys.exit(app.exec_())
To copy to clipboard, switch view to plain text mode 
I was told, that two QApplication can not be run simultaneously. Then what the better solution: QThread, QProcess (again, how to transfer string values between the processes)? Maybe there are other options to render resulting html-code, without QWebEngineView? Any suggestions would help. Thanks.