Mayaのノードアイコンを使ったQStandardItemをつくる!!

Outlinerのように、Viewの中身を色鮮やかにしてみたいなっと思いませんか!?

それがコチラ!

ただのテキストのリストより、アイコンがあることでグッと見やすくなりますね(*´ω`*)

1つ1つアイコンを調べてやっていては大変なので、ノード名をいれれば勝手にアイコンがついてくるカスタマイズしたQStandardItemを作ってみたいと思います!

クラスの骨組み

冒頭に書いたとおり、今回は、「QStandardItem」を継承したクラスにしたいと思います。

「QStandardItem」のコンストラクタは4つありますが、必ずノード名を指定してもらってインスタンスを作ったほうが効率が良さそうなので、「__init__」には文字列の指定が必須にしたいと思います。

from PySide import QtCore
from PySide import QtGui
from maya import cmds

class NodeIconItem(QtGui.QStandardItem):
	def __init__(self, nodeName):
		super(NodeIconItem, self).__init__(nodeName)

アイコンの設定part1

続いて、アイコンの設定の1段階目を見ていきたいと思います。

Mayaにはすべてのノードの種類のアイコンが用意されているわけではないのはご存知でしょうか?ユーザーが追加したノード、特にMayaでアイコンが用意されていないノードは「default」っという名前のアイコンが使用されています。

このクラスでも、アイコンが用意されているか調べていくわけですが、まずはアイコンが見つからなかった時の、デフォルトのアイコンを指定したいと思います。

from PySide import QtCore
from PySide import QtGui
from maya import cmds

class NodeIconItem(QtGui.QStandardItem):
	def __init__(self, nodeName):
		super(NodeIconItem, self).__init__(nodeName)
		
		iconName = ':default.svg'
Mayaのリソースイメージを使用するには、ファイル名の冒頭に「:」を付ける必要があります。詳しくは、「Mayaにある画像をPySideで使う!」で詳しく説明していますので、是非合わせてご覧ください。

アイコンの設定part2

2段階目は、指定されたノード名からノードの種類を調べていきます。

from PySide import QtCore
from PySide import QtGui
from maya import cmds

class NodeIconItem(QtGui.QStandardItem):
	def __init__(self, nodeName):
		super(NodeIconItem, self).__init__(nodeName)
		
		iconName = ':default.svg'
		if cmds.objExists(nodeName):
			nodeType = cmds.nodeType(nodeName)
			shapes   = cmds.listRelatives(nodeName, s=True, pa=True)
			iconName = ':%s.svg' % nodeType
			if nodeType =='transform' and shapes:
				nodeType = cmds.nodeType(shapes[0])
				iconName = ':%s.svg' % nodeType
			
				if nodeType == 'spotLight':
					iconName = ':%s.svg' % nodeType.lower()
			
				if nodeType == 'volumeLight':
					iconName = ':%s.png' % nodeType.lower()

まず、「cmds.objExists」で、指定されたノードが存在するか確認します。もし存在しない場合は、ノードの種類を調べることができないので諦めます。

存在することがわかったら、「cmds.nodeType」を使用して、ノードの種類を調べます。

以外な落とし穴は、Transformノードの場合、表示するアイコンはShapeの種類になるようにしないと、Outlinerのような見た目にすることができません。。。なので、「cmds.listRelatives」を使って、Shapeの有無も調べます(`・ω・´)ゞ

Mayaで用意されたノードのアイコンは、「ノード名.svg」で見つけることができます。

Spot Light、Volume Lightがイレギュラー?でしたので、Resource Browserで調べました。。。(;´∀`)

アイコンの設定part3

アイコンのファイル名を組み立てることはできましたが、まだ本当にアイコンがあるのかは実行してみないと確信はできません。(Spot Lightのようにイレギュラーがありましたしね。。。)

そこで、アイコンが登録されているか「QResource」を使って調べてから設定したいと思います。

class NodeIconItem(QtGui.QStandardItem):
	def __init__(self, nodeName):
		super(NodeIconItem, self).__init__(nodeName)
		
		iconName = ':default.svg'
		if cmds.objExists(nodeName):
			nodeType = cmds.nodeType(nodeName)
			shapes   = cmds.listRelatives(nodeName, s=True, pa=True)
			iconName = ':%s.svg' % nodeType
			if nodeType =='transform' and shapes:
				nodeType = cmds.nodeType(shapes[0])
				iconName = ':%s.svg' % nodeType
			
				if nodeType == 'spotLight':
					iconName = ':%s.svg' % nodeType.lower()
			
				if nodeType == 'volumeLight':
					iconName = ':%s.png' % nodeType.lower()
		
			if not QtCore.QResource(iconName).isValid():
				iconName = ':%s.png' % nodeType
			
			if not QtCore.QResource(iconName).isValid():
				iconName = ':default.svg'
		
		self.setIcon(QtGui.QIcon(iconName))

まず最初に、組み立てたアイコンのファイル名があるか調べます。もしアイコンがなかった場合は、念のため「svg」から「png」に変えてみてもう一度調べてみます。

それでも見つけることができなかったら、諦めてデフォルトのアイコンを使うようにします。

最後に、「setIcon」を使って「QIcon」を設定して終わりです∠( ゚д゚)/

QtGui.QStandardItem(‘persp’)」だったところを「NodeIconItem(‘persp’)」に変えれば、冒頭のようなアイテムを作ることができます!