Approfondissez votre compréhension tout en vérifiant le contenu de vos propres outils un par un, et utilisez-les pour le développement futur d'outils. Comprenez bien 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.
Ralentit la vitesse de mouvement de la caméra dans Maya et permet un réglage fin de la caméra. Les caméras Maya se déplacent parfois légèrement plus vite, ce qui peut être un peu gênant pour un travail délicat de caméra. Normalement, il est ajusté avec les paramètres de l'outil, mais il est difficile à utiliser car il existe des paramètres pour chaque outil de caméra, donc je l'ai unifié. Tournez la molette vers la gauche pour ralentir la vitesse et tournez-la vers la droite pour accélérer, et vous pouvez basculer entre les outils de l'appareil photo.
** Environnement d'exploitation: Maya2019.3, Maya2020.1 ** Puisque j'utilise Pyside2, cela ne fonctionnera pas avant 2016.
cameraSpeedEditor.py
# -*- coding: utf-8 -*-
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin
from PySide2 import QtWidgets
from PySide2.QtCore import Qt
from maya import cmds
class Widget(QtWidgets.QWidget):
def __init__(self):
#Appeler la méthode parente
super(Widget, self).__init__()
#Placer la disposition de la grille
layout = QtWidgets.QGridLayout(self)
#Étiquette de description
labelWidget = QtWidgets.QLabel(u'Ajustez la vitesse de la caméra\n\n ← vitesse de réglage de la vitesse de la caméra lente →')
labelWidget.setAlignment(Qt.AlignCenter)
layout.addWidget(labelWidget,0,0,1,-1)
#Widget de numérotation
self.camDial = QtWidgets.QDial()
self.camDial.setRange(0, 100)
self.camDial.setValue(50)
self.camDial.setNotchesVisible(True)
self.camDial.sliderReleased.connect(self.setCamSpeed)
layout.addWidget(self.camDial,1,0,1,-1)
#Vérifiez le mode super lent
self.checkWidget = QtWidgets.QCheckBox(u'Super lent')
self.checkWidget.setChecked(False)
self.checkWidget.stateChanged.connect(self.setCamSpeed)
layout.addWidget(self.checkWidget,2,0)
#Boîte combinée des outils de l'appareil photo
setCamLabel = QtWidgets.QLabel('set Camera tool:')
setCamLabel.setAlignment(Qt.AlignRight)
layout.addWidget(setCamLabel,3,0)
selCamItem = QtWidgets.QComboBox(self)
selCamItem.addItem('tumble')
selCamItem.addItem('track')
selCamItem.addItem('dolly')
selCamItem.addItem('boxZoomSuper')
selCamItem.addItem('roll')
selCamItem.addItem('yawPitch')
selCamItem.activated[str].connect(self.setTool)
layout.addWidget(selCamItem,3,1)
#Bouton de réinitialisation
resetButton = QtWidgets.QPushButton(u'réinitialiser')
resetButton.clicked.connect(self.resetCamSpeed)
layout.addWidget(resetButton,4,0,1,-1)
#Ensemble de vitesse de la caméra
def setCamSpeed(self):
#Calculer les nombres de vitesse
value = float(self.camDial.value()) **3*0.0000072+0.1
if self.checkWidget.isChecked():
value = value /10
#Définir la valeur calculée
cmds.tumbleCtx( 'tumbleContext' ,e=True ,ts=value)
cmds.trackCtx( 'trackContext' ,e=True ,ts=value)
cmds.dollyCtx( 'dollyContext' ,e=True ,s =value)
cmds.boxZoomCtx('boxZoomContext' ,e=True ,zs=value)
cmds.rollCtx( 'rollContext' ,e=True ,rs=value)
cmds.orbitCtx( 'azimuthElevationContext' ,e=True ,orbitScale=value)
cmds.orbitCtx( 'yawPitchContext' ,e=True ,orbitScale=value)
#Montrez ce que vous avez défini
print ( '# Camera speed is '+str(value)+' !\n'),
#Ensemble d'outils de la caméra
def setTool(self, selectTool):
cmds.setToolTo('%sContext' %(selectTool))
print ( 'Set %s Tool !\n' %(selectTool)),
#Réinitialisation de la vitesse de la caméra
def resetCamSpeed(self):
#Réinitialisez la valeur de chaque caméra à la valeur par défaut
cmds.tumbleCtx( 'tumbleContext' ,e=True ,ts=1)
cmds.trackCtx( 'trackContext' ,e=True ,ts=1)
cmds.dollyCtx( 'dollyContext' ,e=True ,s =1)
cmds.boxZoomCtx('boxZoomContext' ,e=True ,zs=1)
cmds.rollCtx( 'rollContext' ,e=True ,rs=1)
cmds.orbitCtx( 'azimuthElevationContext' ,e=True ,orbitScale=1)
cmds.orbitCtx( 'yawPitchContext' ,e=True ,orbitScale=1)
self.camDial.setValue(50)
self.checkWidget.setChecked(False)
print ( '# Camera speed is Default !\n'),
class MainWindow(MayaQWidgetBaseMixin, QtWidgets.QMainWindow):
def __init__(self):
#Appeler la méthode parente
super(MainWindow, self).__init__()
#Spécifiez le nom et la taille de la fenêtre
self.setWindowTitle('Camera Speed editor')
self.resize(200, 250)
#Widget d'instance et place dans la fenêtre
widget = Widget()
self.setCentralWidget(widget)
def closeEvent(self, event):
#Réinitialiser la vitesse de la caméra lorsque la fenêtre est fermée
widget = Widget()
widget.resetCamSpeed()
def main():
#Fenêtre d'affichage
window = MainWindow()
window.show()
#Traitement lors de l'appel principal
if __name__ == "__main__":
main()
À partir de là, je voudrais expliquer comment chaque code fonctionne, en commençant par le début, tout en me comprenant.
# -*- coding: utf-8 -*-
Si vous utilisez le japonais dans le code, vous devez le mettre. Voir ici pour plus de détails. Cela semble plutôt obsolète en Python3. Maya est toujours 2.7, donc je l'ajouterai juste au cas où.
Nom du code de caractère "Are" écrit au début de la phrase en Python (quelque chose comme UTF-8)
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin
from PySide2 import QtWidgets
from PySide2.QtCore import Qt
from maya import cmds
Importez chaque bibliothèque à utiliser. Python a beaucoup de bibliothèques, vous pouvez donc faire diverses choses en l'utilisant. Je pense que c'est l'un des avantages d'utiliser Python au lieu de MEL.
from 〇〇 import △△
signifie apporter bring in 〇〇.
La fonction de chaque bibliothèque.
** MayaQWidgetBaseMixin **: Utilisé pour définir la relation parent-enfant de la fenêtre
** QtWidgets, Qt **: PySide, fonctions liées à l'interface utilisateur
** cmds **: commande maya
La 4ème ligne «from maya import cmds» est une référence de maya, Il est décrit comme ʻimport maya.cmds as cmds`. Je fais ça parce que c'est plus beau de les avoir tous. Ce que vous faites est probablement la même chose.
class Widget(QtWidgets.QWidget):
def __init__(self):
#Appeler la méthode parente
super(Widget, self).__init__()
...
class。 L'explication de la classe est ici cassée. Veuillez le comprendre dans le livre car c'est compliqué. L'endroit où j'ai le plus trébuché quand je faisais Python. Je me demande si je devrais m'y habituer en l'utilisant.
Je pensais aussi que j'étudiais moi-même, Il est recommandé de lire le livre car il y a une limite aux seuls articles en ligne. Personnellement, [Introduction à O'Reilly Japan Python3](https://www.amazon.co.jp/%E5%85%A5%E9%96%80-Python-3-Bill-Lubanovic/dp/4873117380/ref = sr_1_1? __ mk_ja_JP =% E3% 82% AB% E3% 82% BF% E3% 82% AB% E3% 83% 8A & dchild = 1 & keywords =% E5% 85% A5% E9% 96% 80python3 & qid = 1598490946 & sr = 8-1 ) Est très facile à comprendre. Je lis toujours. Je pense que c'est pour les débutants aux intermédiaires.
[Introduction à O'Reilly Japan Python3](https://www.amazon.co.jp/%E5%85%A5%E9%96%80-Python-3-Bill-Lubanovic/dp/4873117380/ref=sr_1_1? __mk_ja_JP =% E3% 82% AB% E3% 82% BF% E3% 82% AB% E3% 83% 8A & dchild = 1 & keywords =% E5% 85% A5% E9% 96% 80python3 & qid = 1598490946 & sr = 8-1) [Illustration] Qu'est-ce que l'orientation objet? (Signification de l'instance de méthode de classe)
class Widget(QtWidgets.QWidget):
Héritez ** QtWidgets.QWidget ** importé de la bibliothèque dans ** Widget **. C'est comme se préparer à personnaliser la base de PySide2 pour vous-même.
def __init__(self):
__init__
Méthode spéciale. Initialisez la pièce qui est appelée en premier lors de la création de l'instance.
Vous le voyez le plus souvent lorsque vous regardez le code de la classe.
self
Premier argument.
Cela fonctionne pour autre que self, mais par convention ** self ** est toujours utilisé.
Ces règles sont résumées dans le document *** PEP 8 ***, veuillez donc vous y référer.
Peut-être que si vous étudiez en ligne par vous-même, vous ne pourrez pas atteindre ces règles et vous pourrez créer vos propres règles (autodiscipline).
Comprendre Python self et init Qu'est-ce que Python self? Explication de l'utilisation et des précautions Comprendre [les normes de codage Python] PEP8
#Appeler la méthode parente
super(Widget, self).__init__()
Une autre description déroutante. Je ne l'ai pas compris au début, mais ce n'est rien si je le comprends.
Hériter de ** QtWidgets.QWidget ** en ** Widget **,
Si vous créez une méthode d'initialisation avec __init__
, la méthode d'initialisation du parent (QtWidgets.QWidget) ne sera pas appelée.
Alors, mettez cette description et appelez la méthode d'initialisation parente.
Au fait, dans la série python2, cette description était nécessaire, mais dans 3 séries, super () .__ init __ ()
est bien. Facile.
Je me demande quand Maya passera à la série 3. ..
[Python] Héritage de classe (super) Comment utiliser la fonction super () de Python
Pour mieux comprendre ce que fait la classe, illustrons ce qui se passe. 2. Importez PySide2.QtWidgets depuis 7. Hériter du QWidget QtWidgets importé avec le nom Widget 8. Créez une méthode d'initialisation avec la classe Widget 10. Appelez la méthode d'initialisation du QtWidgets.QWidget importé 13 ou version ultérieure Créer la disposition et les fonctions de l'interface utilisateur
Il y a encore beaucoup de personnages, j'ai donc fait une illustration simple.
De cette manière, vous pouvez créer une copie d'occurrence (familière avec Maya) du dessin de conception d'origine et remplacer (écraser) les bras, les jambes et les couleurs pour lui donner la forme souhaitée.
Donc, si vous le remplacez par __init__
, l'original __init__
ne sera pas appelé, vous avez donc besoin de super
.
Bon, l'explication de la classe est devenue longue, mais je vais enfin créer l'interface utilisateur à partir de maintenant.
#Placer la disposition de la grille
layout = QtWidgets.QGridLayout(self)
Créez QGridLayout. Les boutons et les étiquettes seront placés dans cette disposition de grille.
#Étiquette de description
labelWidget = QtWidgets.QLabel(u'Ajustez la vitesse de la caméra\n\n ← vitesse de réglage de la vitesse de la caméra lente →')
Ajout d'étiquettes à la disposition de la grille.
Lorsque vous utilisez un japonais tel que «u'character», préfixez-le avec ** u **.
Vous pouvez commencer une nouvelle ligne avec \ n
.
labelWidget.setAlignment(Qt.AlignCenter)
Placez le widget d'étiquette créé au centre.
layout.addWidget(labelWidget,0,0,1,-1)
Disposition de la grille du widget d'étiquette 0e ligne, 0e colonne, 1ère longueur de ligne, ** - 1 longueur de colonne ** Si vous souhaitez l'utiliser de l'emplacement spécifié jusqu'à la fin, utilisez ** -1 **.
De cette manière, il est possible de spécifier à partir de quelle position dans la ligne ou la colonne sa longueur.
#Widget de numérotation
self.camDial = QtWidgets.QDial()
self.camDial.setRange(0, 100)
self.camDial.setValue(50)
self.camDial.setNotchesVisible(True)
self.camDial.sliderReleased.connect(self.setCamSpeed)
layout.addWidget(self.camDial,1,0,1,-1)
Créez un widget de numérotation.
Cette fois, self.camDial
et self sont ajoutés car je veux extraire la valeur numérique d'un autre endroit.
Spécifiez la plage de 0 à 100. Changement de la valeur par défaut à 50. Ajoutez une échelle avec setNotchesVisible
.
Avec self.camDial.sliderReleased.connect (self.setCamSpeed)
,
Définissez self.setCamSpeed
à exécuter lorsque le bouton de la souris est relâché.
#Vérifiez le mode super lent
self.checkWidget = QtWidgets.QCheckBox(u'Super lent')
self.checkWidget.setChecked(False)
self.checkWidget.stateChanged.connect(self.setCamSpeed)
layout.addWidget(self.checkWidget,2,0)
Créez un widget de vérification.
Spécifiez que la valeur par défaut n'est pas cochée et que self.setCamSpeed
est exécuté lorsque l'état coché est modifié.
La mise en page est organisée dans la 2ème ligne et la 0ème colonne. Si les deux longueurs sont égales à 1, vous pouvez le laisser vide.
#Boîte combinée des outils de l'appareil photo
setCamLabel = QtWidgets.QLabel('set Camera tool:')
setCamLabel.setAlignment(Qt.AlignRight)
layout.addWidget(setCamLabel,3,0)
selCamItem = QtWidgets.QComboBox(self)
selCamItem.addItem('tumble')
selCamItem.addItem('track')
selCamItem.addItem('dolly')
selCamItem.addItem('boxZoomSuper')
selCamItem.addItem('roll')
selCamItem.addItem('yawPitch')
selCamItem.activated[str].connect(self.setTool)
layout.addWidget(selCamItem,3,1)
selCamItem = QtWidgets.QComboBox (self)
Créez une zone de liste déroulante.
Ajoutez plusieurs éléments d'outils de caméra avec ʻaddItem. Je veux utiliser le nom tel quel, il est donc conforme à la description de l'outil de caméra de Maya.
selCamItem.activated [str] .connect (self.setTool)Lorsque l'activité change Exécutez en passant la ** chaîne ** de addItem à
self.setTool`.
#Bouton de réinitialisation
resetButton = QtWidgets.QPushButton(u'réinitialiser')
resetButton.clicked.connect(self.resetCamSpeed)
layout.addWidget(resetButton,4,0,1,-1)
Création d'un bouton de réinitialisation. Définissez les paramètres de fonctionnement et la disposition de la même manière que les autres.
Ceci termine la création de l'interface utilisateur.
Créez le contenu d'opération de ** ~ .connect ** qui est apparu lors de la création de l'interface utilisateur.
#Ensemble de vitesse de la caméra
def setCamSpeed(self):
#Calculer les nombres de vitesse
value = float(self.camDial.value()) **3*0.0000072+0.1
if self.checkWidget.isChecked():
value = value /10
#Définir la valeur calculée
cmds.tumbleCtx( 'tumbleContext' ,e=True ,ts=value)
cmds.trackCtx( 'trackContext' ,e=True ,ts=value)
cmds.dollyCtx( 'dollyContext' ,e=True ,s =value)
cmds.boxZoomCtx('boxZoomContext' ,e=True ,zs=value)
cmds.rollCtx( 'rollContext' ,e=True ,rs=value)
cmds.orbitCtx( 'azimuthElevationContext' ,e=True ,orbitScale=value)
cmds.orbitCtx( 'yawPitchContext' ,e=True ,orbitScale=value)
#Montrez ce que vous avez défini
print ( '# Camera speed is '+str(value)+' !\n'),
Obtenez le statut du cadran et de la case à cocher, Reflète la valeur calculée dans chaque outil de caméra.
value = float (self.camDial.value ()) ** 3 * 0.0000072 + 0.1
Conversion de la valeur de cadran à la valeur de la vitesse de la caméra.
Pourquoi est-ce une formule si étrange, mais quand je l'ai ajustée pour qu'elle fonctionne parfaitement, elle est devenue comme ça.
ʻSi ~ `réduit ** valeur ** à 1/10 lorsque le mode super lent est coché.
# Définissez la valeur calculée ci-dessous
Refléter la valeur calculée dans la valeur de chaque outil de caméra
La raison pour laquelle il y a beaucoup de marge gaspillée est d'aligner les lignes et de les rendre plus faciles à voir.
Il semble que PEP8 n'est pas recommandé, mais j'ose l'ignorer. Comment est-ce en fait?
print ('hogehoge'),
Les derniers **, (virgules) ** sont ajoutés pour être affichés sur la ligne de commande de Maya.
Parce que les avertissements sont colorés et un peu accablants.
Pour l'instant, c'est un mystère pourquoi il peut être affiché sur la ligne de commande avec une virgule. Je me demande si c'est une spécification Maya.
#Ensemble d'outils de la caméra
def setTool(self, selectTool):
cmds.setToolTo('%sContext' %(selectTool))
print ( 'Set %s Tool !\n' %(selectTool)),
** [str] ** reçu de selCamItem.activated [str] .connect (self.setTool)
,
cmds.setToolTo ('% sContext'% (selectTool))
Basculez avec cette commande.
% s remplace% (Honyara)
Exemple:
'%sContext' %('tumble')
→ 'tumbleContext'
#Réinitialisation de la vitesse de la caméra
def resetCamSpeed(self):
#Réinitialisez la valeur de chaque caméra à la valeur par défaut
cmds.tumbleCtx( 'tumbleContext' ,e=True ,ts=1)
cmds.trackCtx( 'trackContext' ,e=True ,ts=1)
cmds.dollyCtx( 'dollyContext' ,e=True ,s =1)
cmds.boxZoomCtx('boxZoomContext' ,e=True ,zs=1)
cmds.rollCtx( 'rollContext' ,e=True ,rs=1)
cmds.orbitCtx( 'azimuthElevationContext' ,e=True ,orbitScale=1)
cmds.orbitCtx( 'yawPitchContext' ,e=True ,orbitScale=1)
self.camDial.setValue(50)
self.checkWidget.setChecked(False)
print ( '# Camera speed is Default !\n'),
Restaurez les paramètres par défaut de la caméra et de l'interface utilisateur.
Avec ce qui précède, l'opération lors de l'utilisation du widget a été créée.
class MainWindow(MayaQWidgetBaseMixin, QtWidgets.QMainWindow):
def __init__(self):
#Appeler la méthode parente
super(MainWindow, self).__init__()
#Spécifiez le nom et la taille de la fenêtre
self.setWindowTitle('Camera Speed editor')
self.resize(200, 250)
#Widget d'instance et place dans la fenêtre
widget = Widget()
self.setCentralWidget(widget)
Héritage de ** MayaQWidgetBaseMixin ** et ** QtWidgets.QMainWindow ** ** MayaQWidgetBaseMixin ** est une fonction pour empêcher la fenêtre de passer sous la fenêtre principale de Maya. J'utilisais des shiboken etc., mais ça fait du bien d'être beaucoup plus simple.
Nouveau! Relation parent-enfant de la fenêtre Maya MayaQWidgetBaseMixin!
Spécifiez le titre et la taille de la fenêtre. Placez le jet comme vous l'avez fait plus tôt au centre de la fenêtre.
def closeEvent(self, event):
#Réinitialiser la vitesse de la caméra lorsque la fenêtre est fermée
widget = Widget()
widget.resetCamSpeed()
Réinitialisez la vitesse de la caméra lorsque la fenêtre est fermée.
Vous pouvez utiliser def closeEvent (self, event):
pour ajouter un comportement supplémentaire lorsque la fenêtre est fermée.
Vous avez maintenant créé l'interface utilisateur et les fonctions principales.
def main():
#Fenêtre d'affichage
window = MainWindow()
window.show()
Si vous appuyez sur main () et la commande, une fenêtre s'affichera et vous pourrez exécuter le programme.
#Traitement lors de l'appel principal
if __name__ == "__main__":
main()
C'est aussi une chose magique. Évitez d'exécuter le programme lors de l'importation. Si vous copiez et collez tout le code dans l'éditeur de script et que vous l'exécutez, le programme démarrera.
Au début, je pensais qu'il s'agissait d'écrire des notes, mais c'est devenu assez long. Si j'ajoute quelque chose que je ne comprends pas en écrivant par endroits, c'est comme ça.
Il me semble bon de laisser un tel article chaque fois que j'écris un outil. Après tout, je pense qu'étudier est quelque chose que vous pouvez apprendre en enseignant → en essayant → en enseignant.
Il se peut que de nombreux endroits ne soient pas accessibles, mais pardonnez-moi. J'apprécierais que vous me disiez s'il y a des erreurs.
Voici le lien du site que j'ai utilisé comme référence.
Nom du code de caractère "Are" écrit au début de la phrase en Python (quelque chose comme UTF-8) Introduction aux modules Python et aux importations depuis [Illustration] Qu'est-ce que l'orientation objet? (Signification de l'instance de méthode de classe) Comprendre Python self et init Qu'est-ce que Python self? Explication de l'utilisation et des précautions Comprendre [les normes de codage Python] PEP8 [Python] Héritage de classe (super) Comment utiliser la fonction super () de Python Nouveau! Relation parent-enfant de la fenêtre Maya MayaQWidgetBaseMixin! [Python] if name == Qu'est-ce que «__ main__» :?
Recommended Posts