Я делаю приложение в PyQt5, которое выполняет множество длительных задач, таких как очистка веб-страниц. Чтобы избежать сбоев в GUI, я использую QThreads и QObjects
В настоящее время у меня есть класс, который наследует QObject и содержит метод для очистки веб-страниц. Я перемещаю этот объект в QThread, соединяю законченный сигнал с методом, который завершает поток, а затем запускаю поток.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import threading
from concurrent.futures import ThreadPoolExecutor
import requests
class Main(QMainWindow):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.init_ui()
self.test_obj = None
self.thread = QThread(self)
def init_ui(self):
widget = QWidget()
layout = QHBoxLayout()
widget.setLayout(layout)
thread_button = QPushButton("Start Thread")
check_button = QPushButton("Check Thread")
layout.addWidget(thread_button)
layout.addWidget(check_button)
thread_button.clicked.connect(self.work)
check_button.clicked.connect(self.check)
self.setCentralWidget(widget)
self.show()
def work(self):
self.test_obj = TestObject()
self.test_obj.moveToThread(self.thread)
self.test_obj.finished.connect(self.finished)
self.thread.started.connect(self.test_obj.test)
self.thread.start()
def check(self):
for t in threading.enumerate():
print(t.name)
@pyqtSlot()
def finished(self):
self.thread.quit()
self.thread.wait()
print("Finished")
class TestObject(QObject):
finished = pyqtSignal()
def __init__(self):
super(TestObject, self).__init__()
def test(self):
with ThreadPoolExecutor() as executor:
executor.submit(self.get_url)
self.finished.emit()
def get_url(self):
res = requests.get("http://www.google.com/")
print(res)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Main()
sys.exit(app.exec_())
Все работает как положено, я получаю:
«Ответ [200]»
"Закончено"
Отпечатано в консоли. Однако, когда я проверяю запущенные потоки, он показывает, что поток dummy-1 все еще работает. Каждый раз, когда я бегу, он создает дополнительный фиктивный поток. В конце концов я не могу больше создавать потоки, и мое приложение вылетает.
Можно ли использовать ThreadPoolExecutor в QThread, как это? Если да, есть ли правильный способ убедиться, что эти фиктивные потоки по-прежнему не запущены после завершения задачи?