Voir la version complète : Résolu Importer script python dans un plugin python
Pandoxyd
26/09/2016, 19h15
Bonjour !
J'ai commencé à créer mon premier plugin en python, pour Cinema4D.
J'aimerais créer une grosse boîte à outils, avec tous mes scripts à l'intérieur, que j'ai créé indépendamment.
Comment puis-je les importer ? En gros, le code de mon plugin serait juste que l'ajout de bouton sur une fenêtre, où chaque bouton lancerait un script différent.
J'ai essayé plusieurs méthodes (placer des fichiers vides '__init__.py', importer en changeant le chemin actuel, placer mes scripts à la racine du plugin, etc...) et j'ai toujours la même erreur : ImportError: no module named MonScript
Si vous avez une idée, je suis preneur :D
Salut,
Si j'ai bien compris tu veux te créer ta propre bibliothèque avec tes fonctions ou classes. Tu as en gros 3 possibilités :
Tu rajoutes ta bibliothèque dans un des dossier utilisé par sys.path
Tu rajoutes un ou plusieurs dossiers "ressource" via le code à sys.path
Tu rajoutes un ou plusieurs dossiers "ressource" via un fichier .pth
1
Pour voir les dossiers qu'utilise le python de c4d, tu peux faire:
import c4d
import sys
def main():
for path in sys.path:
print path
if __name__=='__main__':
main()
Dans mon cas (je suis sur mac), cela m'imprime une dizaine de lignes dans la console qui représentent les dossiers dans lesquels python va chercher des bibliothèques externes. Tu n'as plus qu'à rajouter ta bibliothèque dans un de ces dossier (plutôt les deux derniers, soit le dossier site-packages, ou le dossier personnel de ta session si tu n'as pas les droits admin. Attention de redémarrer c4d pour que cela fonctionne.
2
Tu peux rajouter temporairement un dossier à ta liste sys.path en rajoutant une ligne sys.path.append("Ton/chemin/vers/le/dossier") avant ton import:
import c4d
import sys
sys.path.append("/Users/olid/Documents/BibliosPython")
import olid
def main():
pass
if __name__=='__main__':
main()
[EDIT] et j'allais oublier que tu as la variable __file__ qui te permets de récupérer le chemin de ton fichier, et donc si ta bibliothhèque est dans le même dossier que ton scripts tu peux faire :
import c4d,sys,os
path = os.path.dirname(__file__)
sys.path.append(path)
import maLib
def main():
pass
if __name__=='__main__':
main()
3
Tu peux te créer un fichier avec une extension .pth que tu places dans un des dossier du sys.path (voir exemple 1), dans lequel tu écrits une ligne par dossier que tu veux rajouter. C'est super pratique pour rajouter des bibliothèques externes qui sont déjà utilisées sur le python de ta machine. J'ai un fichier od_path.pth dans le dossier site-packages qui contient ça :
/Library/Frameworks/GEOS.framework/Versions/3/Python/2.7/site-packages
/Library/Python/2.7/site-packages
/Library/Frameworks/GDAL.framework/Versions/1.11/Python/2.7/site-packages
/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/
Là aussi, il faut redémarrer c4d pour que cela fonctionne.
Pandoxyd
27/09/2016, 11h07
Salut oli_d,
Merci pour ta réponse aussi complète que rapide ! J'ai effectivement trouvé comment importer un script externe. J'ai mon pluginsqui possède un dossier "scripts" et je peux maintenant les charger en combinant les deux codes de ta méthode 2 (mon script externe s'appelle "batch.py"):
import c4d
from c4d import bitmaps, gui, plugins
import os, sys
path = os.path.dirname(__file__)
sys.path.append(path) #je pointe vers le chemin du plugin exécuté
sys.path.append(path+"\scripts") #je rajoute le sous dossier 'scripts' afin de loader les différents scripts qui seront placés là
import batch
from batch import *
("Batch.py" est un petit script, avec interface, qui sert à renommer par lot des objets d'une scène)
Le script se lance bien depuis le bouton du plugin, l'interface apparaît grâce à :
def Command(self,id,msg):
if id == RENAMER:
batch.BatchRename()
return True
(BatchRename() étant le 'main' de mon script)
Mais dès que je le manipule (via les boutons de l'interface du plugin), la console me rapporte l'erreur suivante :
"NameError: global name 'doc' is not defined"
Le "doc" correspondant à la ligne 82 de "batch.py" qui est :
objs = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELE CTIONORDER) #Récupération des objets sélectionnés dans l'ordre
Que s'est-il passé ? Dois-revenir dans les chemins des modules de bases de Cinema4D afin qu'il reconnaisse le mot "doc" (qu'il reconnait très bien quand je lance le script seul) ? Ou dois-je déclarer d'une manière plus explicite le module "doc" dans mon script "batch.py" ?
C'est juste que ton doc n'est pas définis (ce qui se passe si tu exécutes via un plugin).
Il faut bien comprendre que doc est une variable faite par c4d pour facilité l'accès au document.
Bref il te suffit de recup le doc courant.
doc = c4d.documents.GetActiveDocument()
objs = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELE CTIONORDER) #Récupération des objets sélectionnés dans l'ordre
Pandoxyd
27/09/2016, 12h03
Super ! :thumbup:
Ça marche en effet, mais je dois le re-déclarer le 'doc' pour chaque fonction qui l'utilise et ce, pour tous mes scripts ? N'y a-t-il pas moyen de déclarer qu'une seule fois dans mon plugin, en tant que global ?
J'ai tenté sauvagement un 'doc = c4d.documents.GetActiveDocument()' au début du code (une première fois du plugin et une fois dans le script), puis des 'global doc' avant de l'utiliser, mais la console me retourne :
ReferenceError: the object 'c4d.documents.BaseDocument' is not alive
Ou je dois remettre à jour tous mes scripts ?
Bha actuellement enfaite tu mets la valeur de retour de GetActiveDocument dans la variable doc. Donc si tu change de doc il faut relancer la fonction.
Donc oui il faut a chaque fois. Sinon tu peux faire doc = c4d.documents.GetActiveDocument
Sans les parentheses comme sa ta variable correspond a la fonction et voila.
Pandoxyd
27/09/2016, 14h30
Ok, ba pas grave, je rendrais mes codes plus propres comme ça.
Merci à vous en tout cas, c'est parfait !
A part ça tu peux toujours aussi appeler ton scripts via un CallCommand(), c'est peut-être plus simple:
Tu ouvre l'historique de script du menu script
Tu lances ton scripts
Tu recopie la ligne CallCommand(xxxxxxx,xxxxxx)#nom_script de l'historique dans ton code
Une autre chose évite d'ajouter un dossier ou un fichier à ton path avec un +:
sys.path.append(path+"\scripts") -> sur mac ça plante
Utilise plutôt os.path.join : sys.path.append(os.path.join(path,"scripts")) Avec ça tu es certain que ça passe sur toutes les plateformes
Sir Gong
28/09/2016, 10h48
Salut Pandoxyd, te voilà membre reconnu.
Powered by vBulletin® Version 4.2.1 Copyright © 2024 vBulletin Solutions, Inc. Tous droits réservés