How to embed a modelPanel into a Qt Layout

1,081 views
Skip to first unread message

unread,
Nov 20, 2011, 12:08:17 PM11/20/11
to python_inside_maya
I want to embed a maya's modelPanel to a Qt's Layout, but i don't know
how?
I just know you can create a window and layouts in QtDesigner and
create the buttons or other controls with coding by PyQt.
But if i want to create a modelPanel with my own camera embed to the
widow created by qt, how?
My english is not good, if you know what i mean, please give me an
answer .

Justin Israel

unread,
Nov 20, 2011, 3:38:34 PM11/20/11
to python_in...@googlegroups.com
Hey there,

You didn't specify if you were actually using PyQt or not. I'm going to assume you want to just use Qt Designer,
and then be able to add your modelPanel to the window. There really isnt much different from creating this purely in the maya ui commands.

win = cmds.loadUI(f="windowTest.ui")
cmds.setParent(win)
cmds.paneLayout()
m = cmds.modelPanel()
cmds.modelPanel(m, e=True, cam="myCamera")
cmds.showWindow( win )
cmds.refresh(f=True)

In my "windowTest.ui" file, I simply created a dialog with nothing in it. And I have a camera in my scene called "myCamera"
Sometimes the new maya ui kinda lags in refreshing itself, so you would have to interact with the new dialog sometimes to
get the camera to redraw.

Are you trying to do this via PyQt? That would have a few more steps since you need to translate between maya node paths and actual Qt widgets.

-- justin

> --
> view archives: http://groups.google.com/group/python_inside_maya
> change your subscription settings: http://groups.google.com/group/python_inside_maya/subscribe

张宇

unread,
Nov 20, 2011, 9:18:57 PM11/20/11
to python_in...@googlegroups.com
Thanks for your reply Justin, I am using pyqt not just the qtDesigner, how to do that with pyqt?

Http://zhangyu.me

Justin Israel

unread,
Nov 20, 2011, 10:07:13 PM11/20/11
to python_in...@googlegroups.com
Hah, ya I had a feeling.
Now that I am home, I was able to write out an example:


Its more complicated because you have to use sip and the MQtUtil function to translate between maya node paths, and QObjects/QWidgets
Here is what the script is doing:

1. Create the layout in PyQt
2. Unwrap it from python into a pointer using sip
3. use the pointer to get the full maya node path
4. set it as the UI parent

Then you create the model panel using the commands module
1. Get a pointer to the underlying widget of the model panel
2. wrap that into a python QObject using sip
3. Add that new object into your layout.

I also added a repaint in the show() method for the QDialog because maya likes to really lag in repainting its interface sometimes, so you wouldnt see the camera redrawn until you interacted with it otherwise.

Let me know if any of that example is unclear. Maybe there is a better way to do this, but this way works fine.

-- justin

Panupat Chongstitwattana

unread,
Nov 20, 2011, 11:15:53 PM11/20/11
to python_in...@googlegroups.com
Wow Justin. Thanks for showing us that example. It's great reference.
Do you cover that in your cmiVFX tutorial too?

Panupat C.

Kurian O.S

unread,
Nov 21, 2011, 12:20:01 AM11/21/11
to python_in...@googlegroups.com
Hi Justin,

thanks for the example man , this is so cool and when I try to run , I got this

# Error: 'parent' is not a Qt property or a signal

# Traceback (most recent call last):

# File "<maya console>", line 9, in <module>

# File "<maya console>", line 14, in __init__

# AttributeError: 'parent' is not a Qt property or a signal #


any idea ? 

--:: Kurian ::--

jo benayoun

unread,
Nov 21, 2011, 1:51:03 AM11/21/11
to python_in...@googlegroups.com
Hi Kurian,

this version works here, I didn't try the justin's one, but the concept stays the same.
its a dummy function, if you need to do more, make a class.


import sip
from PyQt4.QtGui import QMainWindow

from PyQt4.QtGui import QWidget


import maya.cmds as cmds

from maya.OpenMayaUI import MQtUtil


def maya_window():

  return sip.wrapinstance(long(MQtUtil.mainWindow()), QWidget)


def mk_view(name):

  mw = QMainWindow(maya_window())

  mw.setObjectName(name)

  panel = cmds.modelPanel()

  panel = sip.wrapinstance(long(MQtUtil.findControl(panel)), QWidget)

  mw.setCentralWidget(panel)

  mw.setWindowTitle(name)

  mw.resize(1024, 800)

  mw.update()

  return mw


def main():

  mk_view("MyNewWindow").show()

  return 0


main()


hope that help !
jo




2011/11/21 Kurian O.S <kuri...@gmail.com>

Justin Israel

unread,
Nov 21, 2011, 1:59:29 AM11/21/11
to python_in...@googlegroups.com
@Panupat
Actually, no I don't go into this specifically in my PyQt chapter. You do however see the example of how to use sip and MQtUtil to get the reference to the Maya MainWindow. I was trying really hard not to cross a certain threshold of difficulty in my examples for that video,  not to mention that the PyQt section was considered a bonus chapter. I would love to make another video completely dedicated to PyQt at some point and spend much more time on the finer details.

@Kurian
Thats pretty strange. Its complaining that a QDialog doesn't want to accept a 'parent' argument in its init.
Out of curiosity, what version of PyQt are you using?   

from PyQt4 import QtCore; print QtCore.PYQT_VERSION_STR

And this is for Maya 2012? 
I updated the example to not pass in the parent by keyword, but rather by just the 1st argument:

Line 14:    super(MyDialog, self).__init__(parent, **kwargs)

See if that makes a difference for you? It still seems strange to me. Even Qt 4.5.x (which is the version maya 2011 uses) accepts that form of an __init__ signature.

Interested to know if that small change fixes your problem.

-- justin

Justin Israel

unread,
Nov 21, 2011, 2:10:18 AM11/21/11
to python_in...@googlegroups.com
I wonder if wrapping the window to a QWidget vs QObject would make a difference in the problem Kurian was having with my example.
Out of curiosity, Jo does my example work for you properly? I dont have a maya 2011 set up handy to test, and I wonder if I was just using some slight syntax variations that conflict with 2011 qt. Thought maybe he was using 2012.



jo benayoun

unread,
Nov 21, 2011, 2:38:10 AM11/21/11
to python_in...@googlegroups.com
Hi Justin,

Actually, I just wrote the function from scratch. Didn't try your implementation. Did it now. It works fine, for me on 2012 (don't have 2011 too).
To be sure my code always run, I call baseclasses with the oldstyle and never make a use of keyword args (to be compatible with older versions of sip).
The "super" call was mainly designed to resolve baseclasses conflicts in a multiple inheritance case and bringing more features to the metaclass concept.
I make a cast to QWidget, since this is something I probably do in cpp.


jo

Kurian O.S

unread,
Nov 21, 2011, 2:56:23 AM11/21/11
to python_in...@googlegroups.com
Yeah Justin thats what the issue , i updated with code like this 

    def __init__(self, parent=None, **kwargs):

super(MyDialog, self).__init__(parent, **kwargs)


then its working and I am using 4.6


--



--
--:: Kurian ::--

Justin Israel

unread,
Nov 21, 2011, 10:38:09 AM11/21/11
to python_in...@googlegroups.com, python_in...@googlegroups.com
Ok great. Thats good to know. Pyqt 4.6 is slightly older than the maya 2011 docs even suggest (they recommend 4.7.3) so as Jo pointed out in his link its probably a keyword arg compatibility issue. 
Reply all
Reply to author
Forward
0 new messages