Можно ли использовать ThreadPoolExecutor с QThread? Кажется, создать фиктивный поток, который не заканчивается - PullRequest
0 голосов
/ 21 января 2019

Я делаю приложение в 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, как это? Если да, есть ли правильный способ убедиться, что эти фиктивные потоки по-прежнему не запущены после завершения задачи?

...