Maya 2012 中 QT 入门





4.00/5 (1投票)
关于 Maya 2012 中 PyQt 的简短教程。
引言
在本简短教程中,我将引导您完成创建 Maya 2012 的小型插件的步骤,该插件利用 Qt Designer 创建的 Qt 窗体,以及如何添加回调和事件触发器来为我们的 Python 脚本创建用户友好的界面。在本教程的最后,我将向您展示一个示例,说明 Qt 的灵活性以及它如何创建一些动态和创意的 GUI。
请注意,本教程是针对 Maya 2012 的,所有其他版本的 Maya 都未经尝试和测试。
背景
在我们开始之前,我们需要确保我们使用的是 Maya 2012 的 32 位或 64 位版本,并且已经设置好了 Qt 和 PyQt 以供 Maya 使用。如果您还没有安装 Qt 和 PyQt,可以在我的网站 这里 找到一个简短的教程。
如果您过去对 Qt 的 C++ 版本有过很多经验,您会发现 PyQt 在处理回调和事件触发方面遵循非常相似的逻辑。
使用代码
所以 Qt 最好的特性之一就是 Maya 2012 默认自带的图形 UI 设计器。这个程序可以在 Maya.exe 所在的同一个文件夹中找到,通常是 C:\Program Files\Autodesk\Maya2012\bin。
UI 设计器
为了实现这一点,我们有两个主要的类,其中一个类负责存储、添加、删除和获取单个形状数据,而另一个类则更多地用作结构,存储颜色、线宽、位置和形状段等数据。
使用这个程序相当直观,创建一个空白对话框,将项目(在 Qt 中称为小部件)拖到对话框窗口中,调整位置,然后在属性编辑器中分配 objectName 和 text。
objectName 是该特定小部件的唯一名称,所以当我们想在 PyQt 中使用它时,我们将通过其 objectName 来引用它,因此给它们有用且有意义的名称非常重要。每个人都有自己的命名方法,对我来说,通常是小部件上的文本加上类型,例如“addBox_Button”。
在这个演示中,我构建了一个看起来像这样的简单 UI
在这个 UI 中,我们有以下项目
小部件类型 | objectName |
QLineEdit |
objectName_EditBox |
QPushButton |
createBox_Button |
QPushButton |
createSphere_Botton |
QPushButton |
createPlane_Button |
QSpinBox |
scale_SpinBox |
一旦所有这些都设计完成,我们就可以将其保存出来,我建议保存在一个通用的脚本位置,因为你需要硬编码文件的地址,所以不要把它放得太远!!
好的,进入 Maya!!!!!
Maya 端
创意部分已经完成,现在是真正的一部分,Python 脚本编写和连接!加载 Maya 2012 后,让我们打开 Python 编辑器,检查 Qt 和 PyQt 是否正常工作。
我们可以通过运行一个简短的命令来做到这一点,如果一切就绪,它将向控制台打印“Qt is working fine”。
from PyQt4 import * import maya.cmds as cmds print "Qt is working fine"
如果出现错误“# Error: ImportError: No module named PyQt4 #”,那么您的 Qt 和 PyQt 安装存在问题,所以我建议您回到我讨论安装的部分,然后将所有这些问题解决,因为您将无法继续前进。
现在我们已经确认 PyQt 在 Maya 中正常工作,我们可以查看主要的模板脚本,我们可以使用它来加载我们使用 UI 设计器创建的 .UI 窗体,以及支持它的类骨架。
PyQt 有一个很棒的函数用于加载 UI 窗体,它位于 PyQt4 的 uic 部分。使用以下示例在 Maya 中创建 UI,请记住根据您保存文件的位置更改文件路径!
from PyQt4 import QtGui,QtCore, uic import maya.cmds as cmds uifile = 'G:/3D work/Python Scripts/Tuts/Intro to Qt/Intro_UI.ui' form, base = uic.loadUiType(uifile) class CreateUI(base, form): def __init__(self): super(base,self).__init__() self.setupUi(self) def main(): global PyForm PyForm=CreateUI() PyForm.show() if __name__=="__main__": main()
如果我们现在运行这个脚本,您将看到我们拥有与我们设计的 UI 相同的 UI,但是在 Maya 窗口中运行。
现在 UI 已经显示出来了,我们必须考虑连接创建事件时产生的事件处理程序。一个很好的例子是按下按钮时触发的事件。我们可以告诉该事件每次按下特定按钮时运行 UI 类中的特定函数。
确保按钮事件正常工作总是很重要的一步,只是为了确保所有名称都正确。
为此,我们可以将代码直接放入类构造函数中,这样它将在 UI 构建时运行(在 \_\_init\_\_ 函数内),但我个人更喜欢将所有事件处理程序放在一个函数内,这样可以使我的构造函数保持整洁,并且在需要添加更多内容时,有助于我跟踪代码。
代码如下
QtCore.QObject.connect(self.createBox_Button, QtCore.SIGNAL("clicked()"),self.createBox_Fn)
“self.createBox_Button”是我们想要获取的 Qt 小部件的 objectName,所以这里是带有“Create Box”文本的按钮。“clicked()”是我们想要使用的该小部件的事件名称,所以是在按钮被点击时触发。最后,“self.createBox_Fn”是我们希望在触发此事件时运行的函数名称。
在这个例子中,我们将有一个名为“Establish_Connections”的函数,它将包含所有事件调用者,我们通过在 CreateUI 类中定义这个函数来设置它。同时,我们不妨创建 3 个新函数,它们将成为每个对象在被调用时使用事件函数。目前,这些函数只包含一个简单的 Print 命令。
您的代码现在应该看起来像这样
from PyQt4 import QtGui,QtCore, uic import maya.cmds as cmds uifile = 'G:/3D work/Python Scripts/Tuts/Intro to Qt/Intro_UI.ui' form, base = uic.loadUiType(uifile) class CreateUI(base, form): def __init__(self): super(base,self).__init__() self.setupUi(self) self.Establish_Connections() def createBox_fn(self): print "Create Box" def createSphere_fn(self): print "Create Sphere" def createPlane_fn(self): print "Create Plane" def Establish_Connections(self): QtCore.QObject.connect(self.createBox_Button, QtCore.SIGNAL("clicked()"),self.createBox_fn) QtCore.QObject.connect(self.createSphere_Botton, QtCore.SIGNAL("clicked()"),self.createSphere_fn) QtCore.QObject.connect(self.createPlane_Button, QtCore.SIGNAL("clicked()"),self.createPlane_fn) def main(): global PyForm PyForm=CreateUI() PyForm.show() if __name__=="__main__": main()
当我们点击每个按钮时,都会打印出特定的文本。现在是时候使用我们熟悉的 Python 来扩展这些部分了!
Python!!
好的,所有事件处理程序都已就位,Maya 正在创建 UI,是时候添加插件的主体了。由于这更多是 Maya Python 而不是 Qt 或 PyQt,我将对此快速带过。
我们的每个函数(createBox_fn、createSphere_fn 和 createPlane_fn)都需要在运行时运行的代码。
我们要做的就是添加一个简单的 Python 命令来创建这些原始对象,如果按下该按钮。
- Cmds.polyCube()
- Cmds.polySphere()
- Cmds.polyPlane()
这三个函数将创建标准的原语,但我们想做得更进一步!所以我们将从编辑文本框中获取名称,从微调器中获取缩放值。为了做到这一点,我们需要获取这些值。
我们可以使用 self.objectName_EditBox.text() 函数来获取文本框中当前的文本,而 self.scale_SpinBox.value() 将获取微调器控件的值。有了这两者,我们就可以完成脚本了。
目前,self.objectName_EditBox.text() 返回的文本是 QString,它与 Python 字符串不同,但我们可以通过将其封装在 str() 中来将其转换为 Python 字符串。
最终代码应如下所示
from PyQt4 import QtGui,QtCore, uic import maya.cmds as cmds uifile = 'G:/3D work/Python Scripts/Tuts/Intro to Qt/Intro_UI.ui' form, base = uic.loadUiType(uifile) class CreateUI(base, form): def __init__(self): super(base,self).__init__() self.setupUi(self) self.Establish_Connections() def createBox_fn(self): tempName = str(self.objectName_EditBox.text()) tempScale = self.scale_SpinBox.value() cmds.polyCube(n = tempName, h = tempScale, w = tempScale, d = tempScale) def createSphere_fn(self): tempName = str(self.objectName_EditBox.text()) tempScale = self.scale_SpinBox.value() cmds.polySphere(n = tempName, r = tempScale) def createPlane_fn(self): tempName = str(self.objectName_EditBox.text()) tempScale = self.scale_SpinBox.value() cmds.polyPlane(n = tempName, h = tempScale, w = tempScale) def Establish_Connections(self): QtCore.QObject.connect(self.createBox_Button, QtCore.SIGNAL("clicked()"),self.createBox_fn) QtCore.QObject.connect(self.createSphere_Botton, QtCore.SIGNAL("clicked()"),self.createSphere_fn) QtCore.QObject.connect(self.createPlane_Button, QtCore.SIGNAL("clicked()"),self.createPlane_fn) def main(): global PyForm PyForm=CreateUI() PyForm.show() if __name__=="__main__": main()
PyQt 的强大之处
我一直在谈论 PyQt 和 Qt 的强大之处,嗯,我想向您展示一个正在开发的工具 PyNodal 的屏幕截图。这是一个节点式小部件,完全在 Maya 和 PyQt 中编写,它只是展示了 PyQt 和整个系统的灵活性有多大,因为所有的绘图、用户点击和变量都通过我的脚本进行控制。
关注点
尽管本教程本质上很简单,但它希望能帮助一些熟悉 Maya Python 的人进入 Maya 的 PyQt 世界,并让他们体验更大的自由度,将他们的工具提升到一个新的水平。