[Maya Python] Écraser le contenu du script 2 ~ list Notes

Objectif de cet article

Nous approfondirons votre compréhension tout en vérifiant le contenu de vos propres outils un par un, et les utiliserons pour le développement futur d'outils. Je comprends parfaitement que j'ai traversé parce que j'ai travaillé avec le copier-coller jusqu'à présent. J'écris un script de la même manière et cela fonctionne d'une manière ou d'une autre, alors j'espère que cela aidera les gens qui se retrouvent avec. Cette fois, PyQt, QTreeView et QStandardItemModel sont les principaux.

Aperçu des outils

Affiche une liste de notes dans la scène. Chaque nœud a un attribut appelé Notes. Il y a cette fonctionnalité au bas de l'éditeur d'attributs, l'utilisez-vous? Laisser une note ici vous aidera à comprendre ce que fait ce nœud. Je l'utilise souvent pour laisser des notes pour chaque nœud dans le fichier Maya.

Cependant, je n'ai pas trouvé de moyen de lister toutes les notes, alors j'en ai fait un outil.

listNotes.gif Affiche tous les nœuds de la scène où se trouvent les notes, comme une image GIF. Vous pouvez sélectionner des nœuds et modifier des notes.

** Environnement d'exploitation: Maya2019.3, Maya2020.1 ** Puisque j'utilise Pyside2, cela ne fonctionnera pas avant 2016.

Code complet

# -*- coding: utf-8 -*-
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin
from PySide2 import QtWidgets, QtCore, QtGui
from maya import cmds

class Widget(QtWidgets.QWidget):
	def __init__(self):
		super(Widget, self).__init__()

		#Créer une disposition de grille
		layout = QtWidgets.QGridLayout(self)
		
		#Ajout de l'arborescence
		treeView = TreeView()
		layout.addWidget(treeView, 0, 0, 1, -1)
		
		#Paramètres d'élément dans l'arborescence
		self.stockItemModel = StockItemModel()
		treeView.setModel(self.stockItemModel)

		#Sélectionnez le paramètre d'élément dans l'arborescence
		self.itemSelectionModel = QtCore.QItemSelectionModel(self.stockItemModel)
		treeView.setSelectionModel(self.itemSelectionModel)

		#Bouton de sélection
		button = QtWidgets.QPushButton('Select')
		button.clicked.connect(self.select)
		layout.addWidget(button, 1, 0)
		
		#Bouton Actualiser
		button = QtWidgets.QPushButton('Refresh')
		button.clicked.connect(self.refresh)
		layout.addWidget(button, 1, 1)
		
		#Chargement initial
		self.refresh()
		
	#Sélectionner le fonctionnement des boutons
	def select(self):
		cmds.select(cl=True)
		indexes = self.itemSelectionModel.selectedIndexes()
		for index in indexes:
			(node, notes) = self.stockItemModel.rowData(index.row())			
			cmds.select(node, noExpand=True ,add=True)

	#Comportement du bouton Actualiser
	def refresh(self):
		#Créer un dictionnaire vide
		list = {}

		#Obtenir des attributs avec des notes dans le dictionnaire
		for node in cmds.ls(allPaths=True):
			if cmds.attributeQuery ('notes',node=node,exists=True):
				list[node] = cmds.getAttr(node+'.notes')
		
		#Vider le modèle d'article
		self.stockItemModel.removeRows(0, self.stockItemModel.rowCount())
		
		#Ajouter des éléments du dictionnaire récupéré
		for note in list:
			self.stockItemModel.appendItem(note, list[note])
			
					
class TreeView(QtWidgets.QTreeView):
	def __init__(self):
		super(TreeView, self).__init__()

		#Changer le type de sélection (comme Excel)
		self.setSelectionMode(QtWidgets.QTreeView.ExtendedSelection)
		#Changer alternativement la couleur des lignes dans l'arborescence
		self.setAlternatingRowColors(True)
	
		
class StockItemModel(QtGui.QStandardItemModel):
	def __init__(self):
		super(StockItemModel, self).__init__(0, 2)
		#Paramètres d'en-tête
		self.setHeaderData(0, QtCore.Qt.Horizontal, 'Node Name')
		self.setHeaderData(1, QtCore.Qt.Horizontal, 'Notes')

	#Comportement lors de l'édition
	def setData(self, index, value, role=QtCore.Qt.EditRole):
		if role:
			#Obtenir des données modifiées
			(node, attr) = self.rowData(index.row())
			#Modifier les attributs des notes
			cmds.setAttr(node+'.notes', value, type='string')
			#Modifier les éléments modifiés
			self.item(index.row(), index.column()).setText(value)
			
			#Signaler le succès
			return True

	#Nœud de la ligne spécifiée,Renvoie attr
	def rowData(self, row):
		#Obtenir des nœuds et des attributs
		node = self.item(row, 0).text()
		attr = self.item(row, 1).text()
		return (node, attr)

	#Ajouter un article
	def appendItem(self, nodename, notes):
		#Créer un nœud non modifiable
		nodeItem = QtGui.QStandardItem(nodename)
		nodeItem.setEditable(False)
		
		#Les notes sont modifiables et créées
		notesItem = QtGui.QStandardItem(notes)
		notesItem.setEditable(True)

		#Ajouter une ligne
		self.appendRow([nodeItem, notesItem])	
	

class  MainWindow(MayaQWidgetBaseMixin, QtWidgets.QMainWindow):
	def __init__(self):
		super(MainWindow, self).__init__()

		self.setWindowTitle('List Notes')
		self.resize(430, 260)
		
		widget = Widget()
		self.setCentralWidget(widget)

def main():
	window = MainWindow()
	window.show()
	
if __name__ == "__main__":
	main()

Dessin de conception d'outil

listNotes.jpg

Ça ressemble à ça. Il est facile de comprendre si vous dessinez un dessin de conception pour comprendre le fonctionnement de l'outil.

Voir les détails

Voir ci-dessous pour la partie précédemment écrite. J'écrirai sur les nouveaux articles. [Maya Python] Écraser le contenu du script 1 ~ Camera Speed Editor

Paramètres d'apparence de l'arborescence (QTreeView)

		#Ajout de l'arborescence
		treeView = TreeView()
		layout.addWidget(treeView, 0, 0, 1, -1)

Instancez la classe TreeView () et ajoutez-la à la disposition de la grille. À propos, le capital initial du nom de classe est PEP8 Conseillé. Par souci de clarté, je fais la distinction entre les noms de classe avec des acronymes supérieurs et les noms d'instances avec des acronymes inférieurs.

Sautons un peu, mais regardons d'abord la classe TreeView.

class TreeView(QtWidgets.QTreeView):
	def __init__(self):
		super(TreeView, self).__init__()

		#Changer le type de sélection (comme Excel)
		self.setSelectionMode(QtWidgets.QTreeView.ExtendedSelection)
		#Changer alternativement la couleur des lignes dans l'arborescence
		self.setAlternatingRowColors(True)

Héritez QtWidgets.QTreeView dans TreeView. Comme il est essentiellement utilisé tel quel, il y a peu de pièces de remplacement.

self.setSelectionMode(QtWidgets.QTreeView.ExtendedSelection) Changez le mode de sélection. Si vous conservez la valeur par défaut, vous ne pouvez en sélectionner qu'une, alors modifiez-la pour pouvoir en sélectionner plusieurs. ʻExtended Selection` vous permet de sélectionner des pierres volantes comme Excel.

Remarque sur le mode de sélection Qt

self.setAlternatingRowColors(True) Changez alternativement la couleur de la ligne. Une telle vue arborescente devient difficile à voir à mesure que la quantité augmente, alors rendez-la plus facile à voir avec un motif zébré.

ListNotes_TreeView.jpg De cette manière, QTreeView définit l'apparence et le comportement de l'arborescence.

Définir les éléments dans l'arborescence (StockItemModel, QItemSelectionModel)

		#Paramètres d'élément dans l'arborescence
		self.stockItemModel = StockItemModel()
		treeView.setModel(self.stockItemModel)

		#Sélectionnez le paramètre d'élément dans l'arborescence
		self.itemSelectionModel = QtCore.QItemSelectionModel(self.stockItemModel)
		treeView.setSelectionModel(self.itemSelectionModel)

Instancez la classe StockItemModel () avec le nom self.stockItemModel Définissez l'élément créé dans l'arborescence créée précédemment.

Utilisez QtCore.QItemSelectionModel et définissez-le de sorte que vous puissiez obtenir le statut de sélection de self.stockItemModel. Il n'est pas nécessaire de l'hériter et de le remplacer, alors utilisez-le tel quel en tant qu'instance. Définissez self.itemSelectionModel sur treeView avec setSelectionModel comme modèle de sélection.

Regardons maintenant la classe StockItemModel ().

StockItemModel

Initialisation, réglage de l'en-tête (init)

class StockItemModel(QtGui.QStandardItemModel):
	def __init__(self):
		super(StockItemModel, self).__init__(0, 2)
		#Paramètres d'en-tête
		self.setHeaderData(0, QtCore.Qt.Horizontal, 'Node Name')
		self.setHeaderData(1, QtCore.Qt.Horizontal, 'Notes')

Hériter de QStandarItemModel comme StockItemModel. Définissez l'en-tête par défaut.

super(StockItemModel, self).__init__(0, 2) Lors de l'initialisation, créez un modèle d'élément à 0 ligne et 2 colonnes. self.setHeaderData(0, QtCore.Qt.Horizontal, 'Node Name') Créez un en-tête dans la colonne 0 avec le nom Nom du nœud. self.setHeaderData(1, QtCore.Qt.Horizontal, 'Notes') Dans la première colonne, créez un en-tête nommé Notes.

QtCore.Qt.Horizontal est le paramètre d'orientation, ici c'est l'en-tête, alors spécifiez l'horizontale.

Définir l'opération lors de l'édition (setData)

	#Comportement lors de l'édition
	def setData(self, index, value, role=QtCore.Qt.EditRole):
		if role:
			#Obtenir des données modifiées
			(node, attr) = self.rowData(index.row())
			#Modifier les attributs des notes
			cmds.setAttr(node+'.notes', value, type='string')
			#Modifier les éléments modifiés
			self.item(index.row(), index.column()).setText(value)
			
			#Signaler le succès
			return True

Définissez son comportement lors de la modification. ʻIndexspécifie l'emplacement modifié,value spécifie le contenu modifié et rolespécifie le rôle. Spécifiez le format adapté à l'édition avecQtCore.Qt.EditRole`.

À partir de la ligne de données éditées, utilisez la classe rowData pour obtenir node, attr. «rowData» sera décrit plus tard.

cmds.setAttr(node+'.notes', value, type='string') Commande Maya. Reflète les attributs modifiés sur le nœud.

self.item(index.row(), index.column()).setText(value) La pièce modifiée est également reflétée dans les éléments de l'arborescence.

Récupère les nœuds et les attributs de la ligne spécifiée (rowData)

C'est l'explication de la classe rowData qui est sortie plus tôt.

	#Nœud de la ligne spécifiée,Renvoie attr
	def rowData(self, row):
		#Obtenir des nœuds et des attributs
		node = self.item(row, 0).text()
		attr = self.item(row, 1).text()
		return (node, attr)

Renvoie la valeur sous la forme node, attr (nom du nœud, contenu de l'attribut) à partir de la ligne spécifiée.

La classe ʻitempeut obtenir des éléments par (ligne, colonne). Puisqu'il est converti en données d'objet tel quel, il est converti en une chaîne de caractères avec.text ()`.

Ajouter un élément (appendItem)

Créez une fonction pour ajouter des éléments. Après cela, appelez-le à partir d'un bouton ou autre.

	#Ajouter un article
	def appendItem(self, nodename, notes):
		#Créer un nœud non modifiable
		nodeItem = QtGui.QStandardItem(nodename)
		nodeItem.setEditable(False)
		
		#Les notes sont modifiables et créées
		notesItem = QtGui.QStandardItem(notes)
		notesItem.setEditable(True)

		#Ajouter une ligne
		self.appendRow([nodeItem, notesItem])

Ajoutez un élément à partir du nom du nœud, Notes.

QtGui.QStandardItem (nodename) Définit le contenu d'affichage de l'élément. Le nœud nodeItem.setEditable (False) est désactivé. notesItem.setEditable (True) Rendre les notes modifiables.

self.appendRow([nodeItem, notesItem]) Ajoutez les paramètres à la ligne. ʻAppendRow est une fonction de QStandardItemModel`. L'un des atouts de PySide est que vous pouvez utiliser ces fonctions telles quelles.

Créer un bouton

		#Bouton de sélection
		button = QtWidgets.QPushButton('Select')
		button.clicked.connect(self.select)
		layout.addWidget(button, 1, 0)
		
		#Bouton Actualiser
		button = QtWidgets.QPushButton('Refresh')
		button.clicked.connect(self.refresh)
		layout.addWidget(button, 1, 1)

Fondamentalement, c'est la même chose que [Maya Python] Écraser le contenu du script 1 ~ Camera Speed Editor. Ensuite, regardons le contenu du bouton.

Sélectionner le fonctionnement des boutons

	#Sélectionner le fonctionnement des boutons
	def select(self):
		cmds.select(cl=True)
		indexes = self.selItemModel.selectedIndexes()
		for index in indexes:
			(node, notes) = self.itemModel.rowData(index.row())			
			cmds.select(node, noExpand=True ,add=True)

cmds.select (cl = True) Supprime l'état de sélection actuel. selectedIndexes () est une fonction de QItemSelectionModel, qui renvoie une liste d'index sélectionnés.

pour l'index dans les index: Répéter pour le nombre de fois sélectionné. self.itemModel.rowData (index.row ()) Récupère le nom du nœud et les notes de la ligne sélectionnée. Pour plus de détails, reportez-vous à [Obtenir le nœud et l'attribut de la ligne spécifiée (rowData)](### Obtenir le nœud et l'attribut de la ligne spécifiée (rowData)). cmds.select (node, noExpand = True, add = True) Sélectionnez en plus le nœud acquis. noExpand = True vous permet de sélectionner un jeu de sélection plutôt qu'un objet dans le jeu de sélection. ʻAdd = True` Passe au mode de sélection supplémentaire.

Comportement du bouton Actualiser

	#Comportement du bouton Actualiser
	def refresh(self):
		#Créer un dictionnaire vide
		list = {}

		#Obtenir des attributs avec des notes dans le dictionnaire
		for node in cmds.ls(allPaths=True):
			if cmds.attributeQuery ('notes',node=node,exists=True):
				list[node] = cmds.getAttr(node+'.notes')
		
		#Vider le modèle d'article
		self.stockItemModel.removeRows(0, self.stockItemModel.rowCount())
		
		#Ajouter des éléments du dictionnaire récupéré
		for note in list:
			self.stockItemModel.appendItem(note, list[note])

for... Répertoriez les nœuds avec des notes au format dictionnaire.

self.stockItemModel.removeRows(0, self.stockItemModel.rowCount()) Supprimer de la 0ème ligne au nombre de lignes (self.stockItemModel.rowCount ()).

self.stockItemModel.appendItem(note, list[note]) Ajoutez des éléments du dictionnaire récupéré (liste). Voir le [Ajouter un élément (appendItem)](### Ajouter un élément (appendItem)) créé précédemment.

Chargement initial

		#Chargement initial
		self.refresh()

Obtenez Notes la dernière fois que vous le lancez. Il a le même comportement que [refresh](comportement du bouton d'actualisation ###), nous allons donc le réutiliser.

en conclusion

Il y avait de nombreuses descriptions de PyQt cette fois, mais il était assez difficile de collecter des informations en ligne. Si la documentation officielle est un peu plus facile à lire. .. Mais j'ai l'impression d'avoir enfin appris un peu comment utiliser PySide.

Liste de référence

Recommended Posts

[Maya Python] Écraser le contenu du script 2 ~ list Notes
[Maya Python] Écraser le contenu du script 3 ~ Liste des plugins inconnus
[Maya Python] Écraser le contenu du script 1 ~ Camera Speed Editor
Modèle de script python pour lire le contenu du fichier
À propos de la liste de base des bases de Python
Script Python qui compare le contenu de deux répertoires
Notes d'apprentissage depuis le début de Python 1
Notes d'apprentissage depuis le début de Python 2
[Python] Un programme qui fait pivoter le contenu de la liste vers la gauche
[Introduction à Python] Comment trier efficacement le contenu d'une liste avec le tri par liste
[python] Vérifier les éléments de la liste tous, tous
[Python] Trier la liste de pathlib.Path dans l'ordre naturel
Le contenu du didacticiel Python (chapitre 5) est résumé dans une puce.
Le contenu du didacticiel Python (chapitre 4) est résumé dans une puce.
Le contenu du didacticiel Python (chapitre 2) est résumé dans une puce.
Le contenu du didacticiel Python (chapitre 8) est résumé dans une puce.
Le contenu du didacticiel Python (chapitre 1) est résumé dans une puce.
Copiez la liste en Python
Le contenu du didacticiel Python (chapitre 10) est résumé dans une puce.
Le contenu du didacticiel Python (chapitre 6) est résumé dans une puce.
Le contenu du didacticiel Python (chapitre 3) est résumé dans une puce.
Liste des modules python
Script Python pour obtenir une liste d'exemples d'entrée pour le concours AtCoder
[python] Récupère la liste des classes définies dans le module
Récupérer le code retour d'un script Python depuis bat
Ne pas être conscient du contenu des données en python
[Python] Obtenir la liste des noms ExifTags de la bibliothèque Pillow
[Python] Affiche toutes les combinaisons d'éléments de la liste
Vers la retraite de Python2
[Python] Copie d'une liste multidimensionnelle
À propos des fonctionnalités de Python
Simulation du contenu du portefeuille
Le pouvoir des pandas: Python
Essayez d'obtenir la liste des fonctions du paquet Python> os
Obtenez le nombre d'éléments spécifiques dans la liste python
2015-11-26 python> Afficher la liste des fonctions du module> import math> dir (math)
Comment connecter le contenu de la liste dans une chaîne de caractères
Traitez le contenu du fichier dans l'ordre avec un script shell
L'histoire de Python et l'histoire de NaN
[Python] La pierre d'achoppement de l'importation
First Python 3 ~ Le début de la répétition ~
[Python] Afficher uniquement les éléments de la liste côte à côte [Vertical, horizontal]
[python, ruby] sélénium-Obtenez le contenu d'une page Web avec le pilote Web
[Python] [Table des matières Liens] Programmation Python
pyenv-changer la version python de virtualenv
Exportez le contenu de ~ .xlsx dans le dossier en HTML avec Python
Obtenez le chemin du script en Python
[python] Obtenez le rang des valeurs dans la liste par ordre croissant / décroissant
Voir le contenu de Kumantic Segumantion
[Python] Comprendre le potentiel_field_planning de Python Robotics
Revue des bases de Python (FizzBuzz)
python Remarque: map -faire la même chose pour chaque élément de la liste
Premiers pas avec python3
Liste des dépêches en cas de catastrophe du service d'incendie de la ville de Sapporo [Python]
Apprenez les bases de Python ① Débutants élémentaires
Python> sys.path> Liste de chaînes indiquant le chemin pour rechercher des modules
Recevez une liste des résultats du traitement parallèle en Python avec starmap