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?
@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:
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
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