Qt/PySide2/PyQt windows freezes all Blender windows when I try to move Blender's main Window

Continuing my dive into Blender, I’ve been trying to get PySide2 working for a few days now and I’m very close (I think).

Thanks to the great examples provided here and here I’ve gotten a PySide2 GUI up and running while maintaining interactivity with Blender. The issue now is that when I grab Blender’s title bar and try to move it around the whole program locks up (both the Qt and Blender windows).

Not sure if this helps: When Blender locks up I can’t close it, but I can still minimize it and unminimize it, and the title bar still responds to mouse hovers. Also there aren’t any errors that I can see.

I’m not very experienced with Blender’s systems or queues/threading yet, so any help would be appreciated. Thanks!

Hard to say given this is pretty far off the supported path, i’d probably run it in the debugger and see what the main thread is up to.

1 Like

Didn’t think about attaching it to a debugger. I’ll research how to do that, thanks.

Hi, @borbs727 @LazyDodo
I am trying to make a GUI window using python API in Blender. I have tried kivy, PyQt, PySide2, whenever my code execute ones, the GUI window appears according to my program but it completely freezes the blender. I can only minimize and maximize it. And as soon as I close the GUI window, the blender gets crash. I am unable to solve the problem.
I have tried following programs with these GUI tools:

First program with kivy :
###########################################
import kivy
from kivy.app import App
from kivy.uix.label import Label

class MyApp(App):
    def build(self):
        return Label(text = "Oh hello")
    
if __name__ == '__main__':
    MyApp()

###########################################

Second program with PyQt:
###########################################
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel
import sys

def main():
    app = QApplication(sys.argv)
    win = QMainWindow()
    win.setGeometry(200,200,300,300) 
    win.setWindowTitle("My first window!") 
    
    label = QLabel(win)
    label.setText("my first label")
    label.move(50, 50)  

    win.show()
    sys.exit(app.exec_())

main()

###########################################

Third program with PySide2 :
###########################################
from PySide2.QtWidgets import QApplication, QWidget
import sys

class Window(QWidget):
    def __init__(self):
        super().__init__()
 
        self.setWindowTitle("Pyside2 Simple Appplication")
        self.setGeometry(300,300, 500,400)
        
myApp = QApplication(sys.argv)
window = Window()
window.show()
myApp.exec_()
sys.exit(0)

###########################################

I have also tried to plot a graph using matplotlib.pyplot. Same problem is there with blender. When the graph window appears after execution of code, blender gets freeze. But luckily in this case it does not crash on closing the window.

The program with matplotlib is:
###########################################
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0,20,1000)
y = 2*x

plt.plot(x,y)
plt.xlabel('input(x)')
plt.ylabel('output')
plt.title('plot')

plt.plot(x,y,'2'), plt.plot(y,x)
plt.show()

###########################################

If you have found any solution, please share with me. Thanks!

This is not something i have experience with, so I got nothing, sorry.

I haven’t test, but did you guys look at this https://github.com/friedererdmann/blender_pyside2_example
It seems a workaround to use pyside2 with Blender.

It’s likely Blender’s python control of execution goes into the event loop/message pump of the app, preventing Blender from updating its UI.

It’s technically no different from running python in Blender with

while True: pass

Except that the app should break out of the loop when you close it, releasing the hold of the python thread.

You could get around this by running the app in a separate python thread, but that’s potentially a can of worms on sync and resource contention.

Like @kaio above mentions, your UI code essentially blocks the execution of the entire python process which other parts of blender also rely on.

Probably the easiest way is to write your UI as a standalone process (which you can launch on it’s own or, from within blender), and communicate with it using various inter-process-communication methods like a TCP socket, shared memory or named pipes. You can google any of these and find good examples of how to use them in python.

If you want to integrate the UI without creating an other process, you will need to write a non-blocking function that blender can periodically call to handle events happening to your own UI. I’m not that familiar with python UI packages, however they might have alternative methods to the main blocking event loop that lets you handle UI events in a separate function.

Matplotlib for example provides ways to show a plot in a non blocking way, and handle events manually which might let you handle a plot created from within blender (see the docs, or study these examples for details).

1 Like