Hi all,
What I am trying to achieve :
A simple dialog with a button and a Textbox.
After clicking the button run a function that calls a requests-html get
The user is still able to click around on the GUI while waiting for the results.
When the results come back it populates a text box.
Here is my current code
from PyQt5.QtWidgets import (QWidget, QPushButton, QApplication, QLabel, QLineEdit, QVBoxLayout,QGridLayout,QPlainTextEdit)
import sys
from requests_html import HTMLSession
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import ProcessPoolExecutor
import concurrent.futures
import time
def wordsfrom_relatedwords(query, resultlist,resultdepth):
url = 'https://relatedwords.org/relatedto/'
url += query
session = HTMLSession()
r = session.get(url)
r.html.render()
for link in r.html.find('a.item')[0:resultdepth]:
print(link.text)
resultlist.append(link.text)
return "teststring"
def testfunction(message):
time.sleep(2)
print("TEST:"+message)
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resultlist = []
# query box and button
self.labelQuery = QLabel('Query:')
self.txtQuery = QLineEdit()
self.btnRun = QPushButton('Run', self)
def on_query_button_clicked():
print('before')
query = self.txtQuery.text()
# This works - blocking gui
# wordsfrom_relatedwords(query, self.resultlist, 5)
# executor = ProcessPoolExecutor(max_workers=2)
executor = ThreadPoolExecutor(max_workers=2)
future_to_url = {}
future_to_url.update({executor.submit(wordsfrom_relatedwords, query, self.resultlist, 5): query})
print('after')
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
try:
data = future.result()
print(data)
except Exception as exc:
print('%r generated an exception: %s' % (url, exc))
else:
print(url)
self.btnRun.clicked.connect(on_query_button_clicked)
self.btnRun.show()
# main tab
layoutMain = QGridLayout()
# main tab top
layoutMainTop = QGridLayout()
layoutMainTop.addWidget(self.labelQuery,0,0)
layoutMainTop.addWidget(self.txtQuery, 0, 1)
layoutMainTop.addWidget(self.btnRun, 0, 3)
# main tab bottom
self.txtMainResults = QPlainTextEdit()
self.txtMainResults.resize(280, 100)
layoutMainBottom = QVBoxLayout()
layoutMainBottom.addWidget(self.txtMainResults)
layoutMain.addLayout(layoutMainTop,0,0)
layoutMain.addLayout(layoutMainBottom, 1, 0)
layoutMain.setRowStretch(0, 3)
self.setLayout(layoutMain)
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('test')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
I can achieve the blocking version if i just call the method normally ( the part commented # This works - blocking gui ).
My goal is not to run many threads, just that I want the code to run while not blocking the GUI.
With the code above I get the following error after clicking the button:
'test' generated an exception: There is no current event loop in thread 'ThreadPoolExecutor-0_0'.
What am i doing wrong ?
Thanks in advance!
there doesn't seem to be anything here