0

I'm trying to open a second window in a new process to not freeze the main window with PyQt5. For this reason, I define a new class that inherits from multiprocessing.Process and shows the window. This is the main code:

class GuiMain(QMainWindow):
    ...
    # Main window with several functions. When a button is clicked, executes 
    # self.button_pressed()

    def button_pressed(self):
        proc1 = OpenWindowProcess()
        proc1.start()


class OpenWindowProcess(mp.Process)

    def __init__(self):
        mp.Process.__init__(self)
        print(self.pid)

    def run(self):
        print("Opening window...")
        window = QtGui.QWindow()
        window.show()
        time.sleep(10)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    application = GuiMain()
    sys.exit(app.exec_())

The process is created and gets a PID. When run() function is called, the message "Opening window.." is displayed, but nothing else happens. No window, no error... I can't figure out whats happening. Thank you in advance!

edusan1213
  • 359
  • 5
  • 15
  • 1
    Try to use another instance of a `QMainWindow` and call it with the method `exec_()`. But this will keep the process running until the new instance is closed... Why do you let the `OpenWindowProcess` "sleep"? Why do need another process at all? Just create an object in the method connected to the signal of the button press and "show" it... – Sven-Eric Krüger May 09 '18 at 08:37
  • Sorry! Should have read it all. I would also suggest to rather use `QtCore.QThread` than `mp.Process`. – Sven-Eric Krüger May 09 '18 at 08:45
  • This is part of a large project, so I've tried to simplify the example to clarify the problem. I need other process because the new window will display some visual effects and will be monitoring variables that change in real time, and these functions have high computational cost. Regarding the QThread option, I can try but I prefer to run this part of the application on another core (which is posible with multiprocessing but not with threads). The time.sleep is just to see the window for a second. Thank you very much for your response. – edusan1213 May 09 '18 at 08:56
  • I'm goin to try to use another instance of QMainWindow. I did'n know that it could be possible to have several QMainWindows – edusan1213 May 09 '18 at 08:59
  • 1
    "Main Window" is just a name. It is not meant to be something like a singleton or else... – Sven-Eric Krüger May 09 '18 at 09:02
  • Now its working. I've created a new QtApplication and atached to it a new QMainWindow. Thank you very much. – edusan1213 May 09 '18 at 09:26
  • Is your application running on Linux or Windows?... See [Here](https://stackoverflow.com/questions/1289813/python-multiprocessing-vs-threading-for-cpu-bound-work-on-windows-and-linux?rq=1)... – Sven-Eric Krüger May 09 '18 at 11:18
  • Is running on windows, but my intention is to have a portable application. That link is from 2009, much has changed in parallel processing since then. And there is also the fact that initialize a process is more expensive that initialize a thread, so for little tasks, like the ones performed on the examples given in the link (only about a second) a thread is better, but my app does high cost computations (signal processing, machine learning) and for them I think a new process can achieve better performance. But I've not measured it so you made me think about that. Good point, thank you. – edusan1213 May 10 '18 at 11:52

1 Answers1

0

I've come to a solution. You have to create a new QtApplication and attach to it a new QMainWindow instance. This code works fine:

class GuiMain(QMainWindow):
    ...
    # Main window with several functions. When a button is clicked, executes 
    # self.button_pressed()

    def button_pressed(self):
        proc1 = OpenWindowProcess()
        proc1.start()


class OpenWindowProcess(mp.Process)

    def __init__(self):
        mp.Process.__init__(self)
        print("Process PID: " + self.pid)

    def run(self):
        print("Opening window...")
        app = QApplication(sys.argv)
        window = QMainWindow()
        window.show()
        sys.exit(app.exec_())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    application = GuiMain()
    sys.exit(app.exec_())
edusan1213
  • 359
  • 5
  • 15