How to properly load a .ui file in MotionBuilder 2019 with Pyside2?

python
qt
#1

Hello everyone,

This week I met a strange problem about use Pyside2 in Motionbuilder 2019.

I want to use Pyside2 to load a .ui file from Qt Designer for a custom UI.

I modified the ToolNativeWidgetHolder.py file in the script examples and I use QUiLoader to load the .ui file.

The script also has FBWidgetHolder for holding the tool.

The problem is below:

When I open the full script by the script editor in Motion builder 2019, then execute all , it will show the ui I want.

But, when I click the tool button in the Python Tool Manager widget for starting the tool, it will just show a null widget without any element in it. It’s not what I want.

So, how could I properly load the .ui file in MotionBuilder 2019?

I tried the similar UI by building from scratch and It works well in both method above.

Can anyone explain how to properly load a .ui file in MotionBuilder 2019 by Pyside2?

Thank you very much.

Yixiong Xu

2019.07.01

#2

Sounds like an issue with parenting the UI to the widget holder.
Could you post code?

#3

@ldunham1 Good to see you back in the forums! @luckpolar - As @ldunham1 mentioned having pseudo code will be help to debug the issues you’re having. In the mean time i did a quick search - its from 2013, but give you some clues:

-c

#4

Hello,
Thank you for your reply.
Here is a practice for loading a .ui file in motion builder.
import os
import pyfbsdk as fb
import pyfbsdk_additions as fba

from PySide2 import QtWidgets, QtCore
from PySide2 import shiboken2

from PySide2 import QtUiTools


class nativeWidgetHolder(fb.FBWidgetHolder):
    def WidgetCreate(self, pWidgetParent):
        self.motionBuilderMain = MainUI(shiboken2.wrapInstance(pWidgetParent, QtWidgets.QWidget))
        return shiboken2.getCppPointer(self.motionBuilderMain)[0]


class MainUI(QtWidgets.QWidget):
    def __init__(self, parent):
        super(MainUI, self).__init__(parent)
        self.buildUI()

    def buildUI(self):
        self.parent().setLayout(QtWidgets.QVBoxLayout())
        self.currentFileDir = os.path.abspath(os.path.dirname(__file__))
        self.uiDir = self.currentFileDir + '\\testUI.ui'
        self.mainWidget = self.loadUIWidget(self.uiDir)

        self.parent().layout().addWidget(self.mainWidget)

    def loadUIWidget(self, uiFileName, parent=None):
        loader = QtUiTools.QUiLoader()
        uiFile = QtCore.QFile(uiFileName)
        uiFile.open(QtCore.QFile.ReadOnly)
        ui = loader.load(uiFile, parent)
        uiFile.close()
        return ui


class NativeQtWidgetTool(fb.FBTool):
    def __init__(self, name):
        fb.FBTool.__init__(self, name)
        self.mNativeWidgetHolder = nativeWidgetHolder()
        self.BuildLayout()
        self.StartSizeX = 600
        self.StartSizeY = 400

    def BuildLayout(self):
        x = fb.FBAddRegionParam(0, fb.FBAttachType.kFBAttachLeft, "")
        y = fb.FBAddRegionParam(0, fb.FBAttachType.kFBAttachTop, "")
        w = fb.FBAddRegionParam(0, fb.FBAttachType.kFBAttachRight, "")
        h = fb.FBAddRegionParam(0, fb.FBAttachType.kFBAttachBottom, "")
        self.AddRegion("main", "main", x, y, w, h)
        self.SetControl("main", self.mNativeWidgetHolder)

gToolName = "PysideUI"

# Development? - need to recreate each time!!
gDEVELOPMENT = True

if gDEVELOPMENT:
    fba.FBDestroyToolByName(gToolName)

if gToolName in fba.FBToolList:
    tool = fba.FBToolList[gToolName]
    fb.ShowTool(tool)
else:
    tool = NativeQtWidgetTool(gToolName)
    fba.FBAddTool(tool)
    if gDEVELOPMENT:
        fb.ShowTool(tool)

I can load the .ui file from the script editor by just executing all the script.But when I click the tool button in the python tool, it will failed. If I just build from scratch without loadUIWidget() function, it’s OK for both method.
Yixiong Xu
2019.7.11

#5

Hi Chalk,
Thank you for your reply.
I have read the tip and I think it’s a little difference between motion builder 2019 and 2013.
As I known, motion builder 2019 uses Pyside2 and the load .ui method is different from Qt in motion builder 2013. And I want to use the widget holder to hold the tool widget .
Yixiong Xu
2019.07.11