Завершение процесса после закрытия окна

Как завершить выполнение get_products сразу после закрытия окна?

При закрытии окна и повторном запуске приложения всплывает сообщение PyCharm:

'test' is not allowed to run in parallel. Would you like to stop the running one?

from PyQt5 import QtWidgets
import sys, requests


class my_window(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.addButton = QtWidgets.QPushButton(self)
        self.addButton.pressed.connect(get_products)


def get_response(url, headers):
    response = requests.request('GET', url, headers=headers, json={})
    return response.json()


def get_products():
    next_href = 'https://online.moysklad.ru/api/remap/1.2/entity/product?limit=100'
    headers = {
        'Authorization': 'Basic login_password'
    }

    while next_href:
        print(next_href)
        products = get_response(next_href, headers)

        if 'nextHref' in products['meta']:
            next_href = products['meta']['nextHref']
        else:
            next_href = False

        QtWidgets.qApp.processEvents()


app = QtWidgets.QApplication(sys.argv)
window = my_window()
window.show()
sys.exit(app.exec_())

Ответы (2 шт):

Автор решения: S. Nick

Мне показалось, что вам надо использовать дополнительный поток. Попробуйте:

import sys
import requests
from PyQt5 import QtWidgets, QtCore


class Worker(QtCore.QThread):
    stopSignal = QtCore.pyqtSignal(str)
    dataSignal = QtCore.pyqtSignal(object)
    
    def __init__(self):
        super().__init__()
        self.flag = True

    def run(self):
        next_href = 'https://online.moysklad.ru/api/remap/1.2/entity/product?limit=100'
        headers = {
            'Authorization': 'Basic YWRtaW5AamVmZndpbmdjaHVuOjEyMzQ1Ng=='
        }
        while self.flag: 
            products = self.get_response(next_href, headers)
            if products:
                if 'nextHref' in products['meta']:
                    next_href = products['meta']['nextHref']
                    self.dataSignal.emit(next_href)
                else:
                    self.flag = False
                    self.stopSignal.emit("Завершить, т.к. не выполнено 'nextHref' in products['meta']")
            else: 
                self.flag = False  
                self.stopSignal.emit('Завершить выполнение после закрытия окна')

            if not self.flag and 'nextHref' in products['meta']:
                self.stopSignal.emit('Завершить выполнение после закрытия окна')            
        
    def get_response(self, url, headers):
        if self.flag:
            response = requests.request('GET', url, headers=headers, json={})
            return response.json()
        else:
            return False


class MyWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        
        self.next_href = True
        self.addButton = QtWidgets.QPushButton("Start", self)
        self.addButton.pressed.connect(self.button_pressed)

        self.worker = Worker()
        self.worker.dataSignal.connect(self.new_data)
        self.worker.stopSignal.connect(self.stop_signal)        
        
    def button_pressed(self):
        self.worker.start()
        self.addButton.setEnabled(False)
    
    def closeEvent(self, event):
        self.worker.flag = False
        QtCore.QThread.msleep(1000)

    def new_data(self, data):
        print(data)    

    def stop_signal(self, data):
        print(data)
        self.addButton.setEnabled(True)
        self.worker.flag = True


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())
→ Ссылка
Автор решения: Джефф

Найденное решение:

from PyQt5 import QtWidgets
import sys
import requests


class MyWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.addButton = QtWidgets.QPushButton(self)
        self.addButton.pressed.connect(get_products)
        self.exit = False  # флаг выхода из приложения  # ДОБАВЛЕНО
    
    def closeEvent(self, event):  # ДОБАВЛЕНО
        self.exit = True  # выход из приложения  # ДОБАВЛЕНО


def get_response(url, headers):
    response = requests.request('GET', url, headers=headers, json={})
    return response.json()


def get_products():
    next_href = 'https://online.moysklad.ru/api/remap/1.2/entity/product?limit=100'
    headers = {
        'Authorization': 'Basic login_password'
    }

    while next_href:
        if not window.exit:  # ДОБАВЛЕНО
            print(next_href)
            products = get_response(next_href, headers)

            if 'nextHref' in products['meta']:
                next_href = products['meta']['nextHref']
            else:
                next_href = False

            QtWidgets.qApp.processEvents()
        else:  # ДОБАВЛЕНО
            return  # ДОБАВЛЕНО


app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
→ Ссылка