How to create new QMainWidnow objects once the QApp is running?
-
Hi guys,
I have a simple viewer app that is using QMainWindow object (all using PySide2, btw) to display images and/or video. Since I need those to run non-blocking as part of the script, all is created in its own thread. Starting a single viewer works fine, but how do I start another one or more of those?
I have tried to use more QApplication objects, but that one is a singleton, so that doesn't work. Ideal operation would be to start the App in its own thread and open a viewer when needed with the ability to send an image to it.Here is a sample of the code used:
class Viewer(QMainWindow): pass class Display(): def __init__(self, img) self.img = img def worker(self): app = QApplication(sys.argv) self.viewer = Viewer(self.img) self.viewer.show() return app.exec_() def Run(self): self.thread = threading.Thread(target=self.worker) self.thread.start() if __name__ == "__main__": # this part works as planned disp1 = Display() disp1.Run() # this one fails due to the app being a singleton disp2 = Display() disp2.Run()
Any idea how to go about solving this problem?
How to be able to call as many Display objects as needed from the same script?Thanks!
-
@MrAWD said in How to create new QMainWidnow objects once the QApp is running?:
all is created in its own thread
This is not going to work!
All UI stuff must be in the main (GUI) thread!If you have blocking activities then move those in other threads, but not UI.
-
@jsulm said in How to create new QMainWidnow objects once the QApp is running?:
@MrAWD said in How to create new QMainWidnow objects once the QApp is running?:
all is created in its own thread
This is not going to work!
All UI stuff must be in the main (GUI) thread!If you have blocking activities then move those in other threads, but not UI.
The main goal here is to be able to run a python script that handles some images and displays them on the side while it runs. This is somewhat similar to what OpenCV is doing with its cv2.imshow() call. That is why execution of this is moved to the thread to avoid being blocked.
What other option could I try here?
-
@MrAWD said in How to create new QMainWidnow objects once the QApp is running?:
That is why execution of this is moved to the thread to avoid being blocked.
There is no need for a thread: QProcess is assynchronous! Or how do you run that Python script?
Forgot that you're using Python. Only move the heavy calculations into other threads, UI MUST be all in same thread! -
@jsulm said in How to create new QMainWidnow objects once the QApp is running?:
@MrAWD said in How to create new QMainWidnow objects once the QApp is running?:
That is why execution of this is moved to the thread to avoid being blocked.
There is no need for a thread: QProcess is assynchronous! Or how do you run that Python script?
Forgot that you're using Python. Only move the heavy calculations into other threads, UI MUST be all in same thread!Well, since the main script doesn't have any UI stuff there, all of the UI is in the same thread so to speak! :)
What I am trying to do is to open an image and created that Display object and display it. That should followed with another image created and also displayed after the first one (so both are open and you can see differences between those two).
As of using QProcess call here, once you start let say one of the viewers in the separate process, how to communicate with that newly created viewer over there and for example send a new picture to the existing one?
-
@MrAWD
Unless you need some external process, which i don't think you do(?), you won't be usingQProcess
. You will be doing your Python heavy computation within your Python/PySide/Qt program which also displays the UI?If you do need threads for the (non-UI) computation, you will/must use Qt's signals & slots to communicate from the threads to the UI. So the thread signals that it has finished its work and has some result, and the main UI has a slot for that signal, picks up the whatever data, and does the UI, like opening another window to display the data.