Start a process on click

Question:

I am trying to add multiprocessing to my project. To exemplify, I made a little project with just a button, and when the button is pressed, I want to start a process with a method, but the method is never called.
How could I call the method within a process?

Here is my code:

from multiprocessing import Process

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys


class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Python ")
        self.setGeometry(100, 100, 600, 400)
        self.UiComponents()
        self.show()

    def UiComponents(self):
        button = QPushButton("CLICK", self)
        button.setGeometry(200, 150, 100, 30)

        proc = Process(target=self.button_clicked)
        procs = []
        procs.append(proc)

        button.clicked.connect(proc.start)

    def button_clicked(self):
        print("pressed")


App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())
Asked By: bags

||

Answers:

generally mixing both Qt GUI objects and anything that allows threading/multiprocessesing is not safe, and will either not work or cause a segmentation fault.

the correct way to do it without crashing your application is to move the target function to be a function that doesn’t relate to QT GUI. (not a member of any Qt GUI object or has a reference to any Qt GUI object)

also processes can only start once, so you need to create one on every button press as follows:

from multiprocessing import Process

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys

def some_function():
    print("hello")

class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Python ")
        self.setGeometry(100, 100, 600, 400)
        self.UiComponents()
        self.show()

    def UiComponents(self):
        button = QPushButton("CLICK", self)
        button.setGeometry(200, 150, 100, 30)

        self.procs = []

        button.clicked.connect(self.button_clicked)

    def button_clicked(self):
        proc = Process(target=some_function)
        self.procs.append(proc)
        proc.start()
        
        
if __name__ == "__main__":  # for windows compatibility
    App = QApplication(sys.argv)
    window = Window()
    sys.exit(App.exec())

the button is connected to a function which belongs to a Qt object, but the process is connected to a function that is not in any way connected to Qt, and will therefore not crash your application.

Answered By: Ahmed AEK
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.