Maya UI and Pyside 2 together

2,062 views
Skip to first unread message

Lidia Martinez

unread,
Mar 17, 2017, 11:57:39 AM3/17/17
to python_in...@googlegroups.com

Hi folks,

I published an article about embedding Maya's UI into PySide2 for Maya2017.


And again after the first fix I included, I had some errors running this code in a particular case. Maya was telling me '|' or '||' didn't exist.

As you can see on the EDIT section (which is the second edit of the article), I wrote an explanation on how to fix this using setObjectName('layout') on the window and layout  which generates a better UI path:   window|layout|... instead of ||, and seems like Maya likes it better (I guess why).

But then I found out I could even avoid getting the full name that just using setParent('layout')  would work without errors instead of using a path. 



I wanted to understand why this is working, even when I use the same object name with different windows. There's no name clash in Qt, and magically Maya's UI understands setParent anyway...

Any idea why this is happening?



--
Lidia

Marcus Ottosson

unread,
Mar 17, 2017, 12:15:18 PM3/17/17
to python_in...@googlegroups.com

Thanks for sharing this Lidia!

I had a closer look and found that you might not need shiboken2 nor the API to accomplish this.

from PySide2 import QtWidgets
import maya.cmds as cmds

window = QtWidgets.QWidget()
window.resize(500,500)
qtLayout = QtWidgets.QVBoxLayout(window)
qtLayout.setObjectName('viewportLayout') 
cmds.setParent('viewportLayout')
cmds.modelPanel("embeddedModelPanel#", cam='persp')
window.show()

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAAB1%3D8wqJ%3DBqpP06zQCtYqieqtYiOy62V90AcEps_bXD4WejXg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.



--
Marcus Ottosson
konstr...@gmail.com

Justin Israel

unread,
Mar 17, 2017, 4:58:21 PM3/17/17
to python_in...@googlegroups.com
On Sat, Mar 18, 2017 at 5:15 AM Marcus Ottosson <konstr...@gmail.com> wrote:

Thanks for sharing this Lidia!

I had a closer look and found that you might not need shiboken2 nor the API to accomplish this.

from PySide2 import QtWidgets
import maya.cmds as cmds

window = QtWidgets.QWidget()
window.resize(500,500)
qtLayout = QtWidgets.QVBoxLayout(window)
qtLayout.setObjectName('viewportLayout') 
cmds.setParent('viewportLayout')
cmds.modelPanel("embeddedModelPanel#", cam='persp')
window.show()


Lidia's post was partially based on my older post for pre-Maya 2017. And in my post I was using sip and the API to show how to go back from the Maya cmds UI object to Qt again. Is that not needed anymore? This shortened example doesn't include the second part where one might be interested in accessing the modelPanel via Qt.

Also, I vaguely remember going the route of getting the full path to the layout and using that to set it as the parent because of how the parent hierarchy might have been set up. i.e. If the window was already parented to the Maya main window, then its full path might be something like "|MainWindow|MyWindow|MyLayout". So I was ensuring that a fully qualified UI path was passed to setParent(). Not sure if this matters anymore, or if its actually causing Lidia the unreliable behaviour since sometimes it would work and sometimes not depending on the parented objects.

One thing I should have mentioned in my original blog post was the importance of giving everything object names, since the Maya UI relies on those for the full paths. And not setting any of those in between can result in that strange naming of "|MainWindow|Widget|||Something" which then can't be used in commands since it won't find the control.


 
On 17 March 2017 at 15:57, Lidia Martinez <darksi...@gmail.com> wrote:

Hi folks,

I published an article about embedding Maya's UI into PySide2 for Maya2017.


And again after the first fix I included, I had some errors running this code in a particular case. Maya was telling me '|' or '||' didn't exist.

As you can see on the EDIT section (which is the second edit of the article), I wrote an explanation on how to fix this using setObjectName('layout') on the window and layout  which generates a better UI path:   window|layout|... instead of ||, and seems like Maya likes it better (I guess why).

But then I found out I could even avoid getting the full name that just using setParent('layout')  would work without errors instead of using a path. 



I wanted to understand why this is working, even when I use the same object name with different windows. There's no name clash in Qt, and magically Maya's UI understands setParent anyway...

Any idea why this is happening?



--
Lidia

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.



--
Marcus Ottosson
konstr...@gmail.com

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAFRtmOD2NeYiLExwsU5VfhCFDjjDGuOAjLSs_4yn0N-kFsqMPA%40mail.gmail.com.

Marcus Ottosson

unread,
Mar 18, 2017, 6:15:46 AM3/18/17
to python_in...@googlegroups.com

Ah, didn’t notice this in her original example.

Here’s an updated example that fetches the Qt object of a Maya widget and calls a method on it, again without sip or shiboken.

from PySide2 import QtWidgets
import maya.cmds as cmds

def on_button_clicked():
    print("Repainting..")
    modelPanel.repaint()

window = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout(window)
layout.setObjectName("viewportLayout") 

cmds.setParent(layout.objectName())
modelPanel = cmds.modelPanel("embeddedModelPanel#", cam="persp")
modelPanel = window.findChild(QtWidgets.QWidget, modelPanel)

button = QtWidgets.QPushButton("Repaint")
button.clicked.connect(on_button_clicked)
layout.addWidget(button)

window.resize(500,500)
window.show()

Replace PySide2 with PySide and you’ve got your Qt 4 implementation, or use Qt.py for cross-compatibility.

from Qt import QtWidgets

In the name of cross-compatibility with Qt 4 and 5, I’m in the process of disproving the need for sip and shiboken here. The premise being that all can be done with Qt’s findChild alone. If anyone has further examples of sip or shiboken please share. If we can rid the world of these libraries, the transition from Qt 4 to 5 would be that much easier.

Justin Israel

unread,
Mar 19, 2017, 5:23:56 PM3/19/17
to python_in...@googlegroups.com
On Sat, Mar 18, 2017 at 11:15 PM Marcus Ottosson <konstr...@gmail.com> wrote:

In the name of cross-compatibility with Qt 4 and 5, I’m in the process of disproving the need for sip and shiboken here. The premise being that all can be done with Qt’s findChild alone. If anyone has further examples of sip or shiboken please share. If we can rid the world of these libraries, the transition from Qt 4 to 5 would be that much easier.


Are there possibly issues when you have more than once instance of an object that uses the same object name and you are relying on finding the widget by name? findChild() seems like it would work if you are looking for an object that has a unique name under a specific parent. 

I've not tested this workflow, but just throwing out cases where its possible that it could be problematic?
 


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

Marcus Ottosson

unread,
Mar 20, 2017, 9:28:36 AM3/20/17
to python_in...@googlegroups.com

Thanks, that’s a good suggestion. Though I wonder whether the MQtUtil.findControl() wouldn’t be suffering from the same consequence, both being driven by the object name of widgets.​

# With
pointer = MQtUtil.findControl("someName")
widget = shiboken2.wrapInstance(long(ptr), QtWidgets.QWidget)

# Without
widget = window.findChild(QtWidgets.QWidget, "someName")

Where the Maya-approach is looking for a widget on a global scale, with more room for collision, and the Qt-based approach is looking in just the window.

Reply all
Reply to author
Forward
0 new messages