如何通过PySide获取Maya主窗口指针?

5 投票
3 回答
13007 浏览
提问于 2025-04-17 21:49

我在Maya中使用过很多PyQt4,通常我发现切换到PySide挺简单的,但我在获取主窗口的指针时遇到了一些问题。也许有人能理解哪里出了错。

这是我在PyQt4中做的:

import sip, PyQt4.QtCore
import maya.OpenMayaUI as mui
ptr = mui.MQtUtil.mainWindow()
parent = sip.wrapinstance(long(ptr), PyQt4.QtCore.QObject)

这个没问题。当我在PySide中尝试相同的操作时:

import sip, PySide.QtCore
import maya.OpenMayaUI as mui
ptr = mui.MQtUtil.mainWindow()
parent = sip.wrapinstance(long(ptr), PySide.QtCore.QObject)

我遇到了以下错误:

# Error: wrapinstance() argument 2 must be sip.wrappertype, not Shiboken.ObjectType
# Traceback (most recent call last):
#   File "<maya console>", line 4, in <module>
# TypeError: wrapinstance() argument 2 must be sip.wrappertype, not Shiboken.ObjectType # 

有人知道哪里出错了吗?

3 个回答

0

根据你的需求,下面这些更新的代码可能会更容易使用。因为现在Maya有了一个内置的方法,可以直接访问Qt中的主窗口。

import pymel.core as pm
mayaWindow = pm.ui.Window("MayaWindow").asQtObject()
your_widget.setParent(mayaWindow)
4

因为之前的回答有点过时了,这里提供一个更新的版本,省得有人还要自己去更新。

获取Maya主窗口有两种方法:

  • 使用PySide2:
from PySide2 import QtWidgets

global app
app = QtWidgets.QApplication.instance() #get the qApp instance if it exists.
if not app:
    app = QtWidgets.QApplication(sys.argv)


def getMayaMainWindow():
    mayaWin = next(w for w in app.topLevelWidgets() if w.objectName()=='MayaWindow')

    return mayaWin

print(getMayaMainWindow())
  • 使用shiboken2和Maya的API:
import maya.OpenMayaUI as apiUI
from PySide2 import QtWidgets

try:
    import shiboken2
except:
    from PySide2 import shiboken2


def getMayaMainWindow():
    ptr = apiUI.MQtUtil.mainWindow()
    mayaWin = shiboken2.wrapInstance(long(ptr), QtWidgets.QWidget)

    return mayaWin

print(getMayaMainWindow())
15

你需要导入 shiboken 而不是 sip,并且在调用 wrapInstance 时要传入 QWidget,而不是 QObject

补充说明: Maya2017 里包含了 shiboken2PySide2,而不是下面评论提到的 shibokenPySide

import shiboken
from PySide import QtGui, QtCore
import maya.OpenMayaUI as apiUI

def getMayaWindow():
    """
    Get the main Maya window as a QtGui.QMainWindow instance
    @return: QtGui.QMainWindow instance of the top level Maya windows
    """
    ptr = apiUI.MQtUtil.mainWindow()
    if ptr is not None:
        return shiboken.wrapInstance(long(ptr), QtGui.QWidget)

请注意,sip 中的 wrapinstance 里的 i 是小写的,而在 shiboken.wrapInstancei 是大写的。

shiboken.wrapInstance() 需要一个第二个参数叫做 wrapertype,所以你可以把 QWidget 作为第二个参数传进去。

撰写回答