PDA

View Full Version : Passing string to QThread (QProcess?) and out



NewPyQt
20th March 2017, 00:51
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

self.get_thread = getGoogle(self.text)
which is wrong.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import sys
from bs4 import BeautifulSoup
from PyQt5.QtWidgets import QApplication, QWidget, \
QLabel, QLineEdit, QGridLayout, QPushButton
from PyQt5.QtCore import pyqtSignal, QEventLoop, QThread
from PyQt5.QtWebEngineWidgets import QWebEngineView
from requests import get


class getGoogle(QThread):
def __init__(self):
QThread.__init__(self)
self.text=text

def __del__(self):
self.wait()

def render(source_html):
class Render(QWebEngineView):
def __init__(self, html):
self.html = None
self.app = QApplication([])
QWebEngineView.__init__(self)
self.loadFinished.connect(self._loadFinished)
self.setHtml(html)
while self.html is None:
self.app.processEvents(QEventLoop.ExcludeUserInput Events | QEventLoop.ExcludeSocketNotifiers | QEventLoop.WaitForMoreEvents)
self.app.quit()

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

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

return Render(source_html).html

def search(self, text):
query=str(text)
query = query.replace(" ", "+")
url='https://www.google.com/search?q=' + query
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'}
sample_html = get(url, headers=headers).text
soup = BeautifulSoup(self.render(sample_html), "html.parser")
res = soup.find('span', attrs={'class': 'cwcot'})
res = res.get_text()
return res

def run(self):
result=self.search(text)
self.emit(pyqtSignal('add_answer(QString)'), result)
self.sleep(2)


class MyApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()

def initUI(self):
self.sendButton = QPushButton('Ask', self)
self.questionEdit = QLineEdit(self)
self.answer=QLabel(self)
grid = QGridLayout(self)
grid.setSpacing(10)
grid.addWidget(self.questionEdit, 1, 0)
grid.addWidget(self.sendButton, 1, 1)
grid.addWidget(self.answer, 2,0)
self.sendButton.clicked.connect(self.getAnswer)
self.setLayout(grid)
self.resize(500, 100)
self.show()

def getAnswer(self):
text = self.questionEdit.text()
if len(text)>=1:
self.get_thread = getGoogle(self.text)
self.connect(self.get_thread, pyqtSignal("add_answer(QString)"), self.answer.setText)
self.get_thread.start()
else:
self.answer.setText("Specify your question")

if __name__ == '__main__':
app = QApplication(sys.argv)
my = MyApp()
sys.exit(app.exec_())
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.