techartorg / bqt

A Blender add-on to support & manage Qt Widgets in Blender (PySide2)
https://github.com/techartorg/bqt/wiki
Mozilla Public License 2.0
172 stars 25 forks source link

Draft: Cherry picking changes since 0.0.1 #42

Closed friedererdmann closed 1 year ago

friedererdmann commented 1 year ago

I'm running into some issues with current Master, so I've started a new branch and manually made some changes back to how they were on 0.0.1.

This is currently just for myself to compare what changes have come in and what's working and what's not working.

hannesdelbeke commented 1 year ago

what are the issues you have?

friedererdmann commented 1 year ago

what are the issues you have?

In latest Master a number of things don't work at the moment :( The demo scripts are mixing Qt, PySide2 and PyQt5 imports, so it makes it hard to check what's working and what's not (plus the demo scripts needed some fixing to work in PySide2 at least).

Secondly, I could not at all focus the window right now and only interact with the mouse.

Also I'm still getting a number of crashes on Blender closing like so:

Error   : EXCEPTION_ACCESS_VIOLATION
Address : 0x00007FFB5151C23C
Module  : python310.dll
Thread  : 00005280

I think this last one requires us to switch from inheriting QApplication to creating one, but I wasn't able to test much until now.

hannesdelbeke commented 1 year ago

Secondly, I could not at all focus the window right now and only interact with the mouse.

that sounds like the focus script is not running. is this on blender start, or when you go out of blender and back into it? do you have any errors in the terminal? maybe the startup scripts failed to run and register the focus operator.

number of crashes on Blender closing

this is more worrying. could be qt, or ctypes which we use for wrapping blender window and releasing keys on refocus.

i'm not able to repro either of these issues

hannesdelbeke commented 1 year ago

ok i managed to repro the EXCEPTION_ACCESS_VIOLATION, when starting blender from console. will look into what causes it

hannesdelbeke commented 1 year ago

looking into this, my guess is this is caused by the PR that changed the way blender handles closign the application https://github.com/techartorg/bqt/pull/34 scratch that

hannesdelbeke commented 1 year ago

i also have the exception on the old commit from bob white 8437e061b74f1a692ef16b2174144cf5e25120f2. but it seems to be pyside2 only? need more testing

Exception ignored in atexit callback: <function on_exit at 0x0000028EC7650CA0>
Traceback (most recent call last):
  File "C:\Users\hanne\OneDrive\Documents\repos\BlenderTools\modules\vendorstartup\bqt\__init__.py", line 142, in on_exit
    app.store_window_geometry()
  File "C:\Users\hanne\OneDrive\Documents\repos\BlenderTools\modules\vendorstartup\bqt\blender_applications\blender_application.py", line 138, in store_window_geometry
    settings.setValue(self._settings_key_geometry, self.blender_widget.geometry())
AttributeError: 'Win32BlenderApplication' object has no attribute 'blender_widget'
Error   : EXCEPTION_ACCESS_VIOLATION
Address : 0x00007FFB947AC23C
Module  : python310.dll
Thread  : 00003f5c
Writing: C:\Users\hanne\AppData\Local\Temp\blender.crash.txt

but likely cause i dont have win32gui NameError: name 'win32gui' is not defined

still have the access violation on your branch where we dont inherit qapp

hannesdelbeke commented 1 year ago

when i disable the focus operator i dont get the access violation

hannesdelbeke commented 1 year ago

shouted too early again ...

hannesdelbeke commented 1 year ago

my current theory: blender is wrapped in a qwindow. and pyside tries to delete the qwindow on closing blender in runCleanupFunctions , but it can't cause it's not python but c.

Stack trace:
python310.dll       :0x00007FFB75CCBE70  PyType_GenericNew
python310.dll       :0x00007FFB75C78400  PyDict_MaybeUntrack
shiboken2.abi3.dll  :0x00007FFB7DD07020  MakeQAppWrapper
pyside2.abi3.dll    :0x00007FFB7CA122A0  PySide::destroyQCoreApplication
pyside2.abi3.dll    :0x00007FFB7CA139B0  PySide::runCleanupFunctions
QtCore.pyd          :0x00007FFB711A98D5  Symbols not available

there seems to be no way to unwrap a window once it's wrapped with qwindow.fromWInID() so not sure how to work around this. nothing i tried was successfull

wonder if this could be the affected widget. when trying to get the parent from the blender widget python returns an exception instead please note first time you run this in blender it works, but second time you get error.

from PySide2.QtWidgets import QApplication
app = QApplication.instance()
a = app._blender_window.parent() 

# first time
# <PySide2.QtGui.QWindow(0x1e6a52d5120, name="QWindowContainerClassWindow") at 0x000001E6A66E7340>

# second
# Error: Python: Traceback (most recent call last):
#  File "\Text", line 3, in <module>
# RuntimeError: Internal C++ object (PySide2.QtGui.QWindow) already deleted.

same if you try access the children, or any other attr

hannesdelbeke commented 1 year ago

updated above code, had a small error in sample code resulting in the error not being thrown

hannesdelbeke commented 1 year ago

when running above code twice in the blender script editor, the ACCESS VIOLATION dissapears on exit 🤔 it's still there if we run it only once in the script editor

however running this code twice in any scripts, e.g. in on_exit doesn't fix the ACCESS VIOLATION. 😖

this does seem to prove it's related to garbage collection stuff from either pyside or python

hannesdelbeke commented 1 year ago

ok think i found the issue.

QApplication is instanced, and a reference is saved in a variable in the QOperator. the blender window is wrapped in QT, and is now managed by pyside/ the QApplication

when closing blender, operators likely get deregistered, which means the reference to QApplication is gone, and QApplication gets garbage collected. but blender is managed by the QApp, which tries to delete all it's widgets etc.

since the operator owns qapp, qapp owns blender, and blender owns the operator. we have a loop.

moving the qapp to a global variable instead of the operator seems to fix the access violation error :D

ewerybody commented 1 year ago

ok think i found the issue.

QApplication is instanced, and a reference is saved in a variable in the QOperator. the blender window is wrapped in QT, and is now managed by pyside/ the QApplication

when closing blender, operators likely get deregistered, which means the reference to QApplication is gone, and QApplication gets garbage collected. but blender is managed by the QApp, which tries to delete all it's widgets etc.

since the operator owns qapp, qapp owns blender, and blender owns the operator. we have a loop.

moving the qapp to a global variable instead of the operator seems to fix the access violation error :D

Ah see! I didn't look into the PRs yet :D just the issues and found #47 I also had this error and had no clue how to solve it. Before asking the Qt people I wanted to try with latest PySide6 and that already solved the issue 🤷.

How is this going forward? Would you want a fork for PySide6 or wrap it so it handles 2 and 6 simultaneously? There aren't so many calls so this should be slim and would not require some beast like qtpy.

hannesdelbeke commented 1 year ago

both of them live in main at same time would be ideal.

aim to stay on the vfx platform version which is not yet pyside6. But personally i d prefer pyside6 i think.

hannesdelbeke commented 1 year ago

save dialogue is implemented in PR #56
now closing this PR since everything is addressed in individual PRs.