BQT: custom UI for add-ons & tool in Blender with PyQt or PySide

BQT let’s you create completely custom UI for your tools and addons with the QT library.
sample_blender_2way

fully custom UI

Instead of feeling limited by N-Panel only UI. Do whatever you want.

cross app

Qt widgets run nativaly in Krita, 3ds Max, Maya, … and are great to use in cross dcc pipelines.
There are already hundreds of QT widgets out on GitHub. Which you can just reuse.

Themed

BQT ships with a basic blender theme, so qt widgets will by default look similar to Blender.

Tech talk

  • The blender window is wrapped in a QWindow, so you can parent your widgets to it. To prevent them dissapearing in the background when using Blender.
  • The parenting also prevents your widget from being garbage collected.

Note that using operators from a QT window often is quite buggy. Try to not use any operators. If you do, use context override to set the window.

Installation

  • You can get the latest add-on from the repo: https://github.com/techartorg/bqt
  • You also need to pip install PySide2
  • since bqt is now an add-on, you need to enable it in Preferences

It has undergone major updates recently, so if you tried it in the past and had issues. These might now be resolved. Feel free to report issues here https://github.com/techartorg/bqt/issues

4 Likes

theres 2 problems ,

A) the preferences window also gets wrapped and when i close it, the whole blender program closes.
B) the preferences window doesnt stay on top of the blender main window anymore. All other subwindows do behave correctly though, so it should be fixable relatively easy

Yes that’s an anoying issue.
It happens when on startup the wrong window is wrapped.
The wrapped window, is the one with title Blender qt.
image

yesterday I submitted an attempted fix for this.
Since there’s AFAIK no way to know which window is the main blender window, bqt wraps the largest window. If your preferences window on startup is larger than the blender window, it will wrap the preferences.

The wrapped qt window becomes the main window. so if you close that one, it closes Blender.

You can disable the wrapping with the env var BQT_DISABLE_WRAP set to 1. But then widgets wont stay in foreground.

the problem seems to be that blender exposes no window class for its windows … they are all just ghostclass (no class), there is no way to know which window is which … i think when bqt is merged into blender this could be fixed in one go ?

i changed my startup file so the preferences arent open on startup … now it seems to work correctly

tbh i don’t see that happen soon.

  • the easiest would be if the devs added a bpy method to get the window-handle of the main window.
  • or if blender could parent any window to blender like unreal’s parent_external_window_to_slate

FYI, GHOST is the underlying UI framework of Blender. So GHOST class refers to a class from that UI framework, not to a no-class class (which you call ghost-class)

2 Likes

ahhh ok i misunderstood that then … all other programs on my pc have a custom window class/name (often with a comprehensive naming) for all of their windows and subwindows though.
it would make things a bit easier, also for external tools, to interact with blender.

think i found the solution :smiley: , will merge it in later. tested and seems to work.
if there’s no parent handle, (0) it’s the main window

parent_hwnd = ctypes.windll.user32.GetParent(win.hwnd)
if parent_hwnd == 0:
    blender_windows = [win]
    break
1 Like

merged the fix for wrapping the main window in the bqt repo. now having preferences open should be possible without causing wrap issues.

various updates

  • widgets can stay in front if blender is not wrapped in qt (more stable)
  • widgets can be auto discovered and added (parented) to bqt
  • widgets can be enforced unique using the objectname, to avoid opening the same tool twice
  • fixed various bugs
    • notable bug: settings are not saved on closing blender
  • after years of outdated pip packages, bqt released a new version to PyPI (for pip install)