1

I have a simple GUI app running using PyQt6 When I start the application i create 4 threads, each one executing a different task in an infinite loop. I create a list of threads to manage them easily.

def create_threads(self):
        self.threads, self.workers = [], []

        self.workers.append(GetRamUsageWorker(self.libRKM))
        self.workers[0].progress.connect(self.update_ram_usage_graph)
        self.threads.append(QThread())

        self.workers.append(GetCpuInfoWorker(self.libRKM))
        self.workers[1].progress.connect(self.update_cpu_info)
        self.threads.append(QThread())

        self.workers.append(GetGpuInfoWorker(self.libRKM))
        self.workers[2].progress.connect(self.update_gpu_info)
        self.threads.append(QThread())

        self.workers.append(GetCurrentGovWorker())
        self.workers[3].progress.connect(self.update_curr_gov_combobox)
        self.threads.append(QThread())

        for i in range(len(self.threads)):
            self.workers[i].moveToThread(self.threads[i])
            self.threads[i].started.connect(self.workers[i].run)
            self.workers[i].finished.connect(self.threads[i].quit)
            # self.workers[i].finished.connect(self.workers[i].deleteLater)
            # self.threads[i].finished.connect(self.threads[i].deleteLater)
            self.threads[i].start()

the problem is, when i try to close the application, the process just hangs in terminal.

This is the code i tried earlier, but with no result:

def closeEvent(self, event):
        self.terminate_threads()
        event.accept()
        QtWidgets.QMainWindow.closeEvent(self, event)

def terminate_threads(self):
    for i in range(len(self.threads)):
        self.workers[i].stop()

And this is an example of my workers, they are pretty similar to each other

class GeneralWorker(QObject):
    progress = pyqtSignal(str)
    finished = pyqtSignal()

    def __init__(self):
        super().__init__()
        self.isRunning = True

    def stop(self):
        logging.debug("stop")
        self.isRunning = False

class GetRamUsageWorker(GeneralWorker):
    def __init__(self, libRKM: ctypes.CDLL):
        super().__init__()
        self.libRKM = libRKM

    def get_ram_usage(self):
        memstats = self.libRKM.memory_percentage
        memstats.restype = ctypes.c_float
        percent = memstats()
        text = str(float(f'{percent:.2f}'))
        return text

    def run(self):
        while self.isRunning:
            text = self.get_ram_usage()
            time.sleep(1)
            self.progress.emit(text)
        self.finished.emit()

I am searching for a way to close the application properly. If the approach i used is totally wrong i would be happy to change it following your advice. Thank you.

Gino_P
  • 74
  • 7

0 Answers0