Un petit problème qui m'a valu une bonne prise de tête :
J’ai longtemps cru que les dialogues asynchrones, c’est à dire un dialogue que l’on peut « docker » et qui reste actif sans bloquer les autres fonctionnalités, étaient réservés aux plugins dans Cinema4D. Puis un jour je tombe sur un bout de code qui fonctionnait, même avec un script. J'ai pensé que c'était une amélioration de la r17. Je développe un super dialogue, je copie je colle dans un autre script et paf, cela ne marchait plus. J'ai mis un bon moment à trouver pourquoi et je vous livre mes conclusions.
Un exemple simple :
Si on lance le script et que l'on essaie de modifier la taille de la fenêtre, le contenu disparaîtCode PHP:
import c4d
class MonDlg( c4d.gui.GeDialog):
def CreateLayout(self):
self.AddStaticText(1000, c4d.BFH_SCALE|c4d.BFV_SCALE, initw=100, inith=20,name = 'Hello world !')
return True
def main():
dlg = MonDlg()
dlg.Open(c4d.DLG_TYPE_ASYNC)
if __name__=='__main__':
main()
En fait c'est une bête histoire de portée de variables, la variable dlg est effacée à la fin du code. Par contre si je déclare dlg en global tout fonctionne:
Sinon plus simplement, si on crée notre dialogue dans if __name__=='__main__': sans passer par une fonction, tout va bien !Code PHP:
import c4d
class MonDlg( c4d.gui.GeDialog):
def CreateLayout(self):
self.AddStaticText(1000, c4d.BFH_SCALE|c4d.BFV_SCALE, initw=100, inith=20,name = 'Hello world !')
return True
def main():
global dlg
dlg = MonDlg()
dlg.Open(c4d.DLG_TYPE_ASYNC)
if __name__=='__main__':
main()
Code PHP:
import c4d
class MonDlg( c4d.gui.GeDialog):
def CreateLayout(self):
self.AddStaticText(1000, c4d.BFH_SCALE|c4d.BFV_SCALE, initw=100, inith=20,name = 'Hello world !')
return True
if __name__=='__main__':
dlg = MonDlg()
dlg.Open(c4d.DLG_TYPE_ASYNC)
Dernière modification par oli_d ; 03/12/2015 à 07h43.
Salut oli_d,
Merci pour l'info !
Ma petite contribution évitant la création d'une variable dans le scope global :
En reprenant le même code d'appel, il suffit de garder une référence de chaque object créé dans une liste statique à la classe Dialog :
Sans toucher au code de la classe, on peut conserver une référence du dialog en tant que variable statique de la fonction main :Code PHP:
import c4d
class Dialog(c4d.gui.GeDialog):
__dialogs = []
def CreateLayout(self):
self.AddStaticText(1000, c4d.BFH_SCALE | c4d.BFV_SCALE, initw=100, inith=20, name='Hello world !')
return True
def Open(self, *args, **kwargs):
super(Dialog, self).Open(*args, **kwargs)
self.__dialogs.append(self)
def main():
dlg = Dialog()
dlg.Open(c4d.DLG_TYPE_ASYNC)
if __name__=='__main__':
main()
Code PHP:
import c4d
class Dialog(c4d.gui.GeDialog):
def CreateLayout(self):
self.AddStaticText(1000, c4d.BFH_SCALE | c4d.BFV_SCALE, initw=100, inith=20, name='Hello world !')
return True
def main():
dlg = Dialog()
dlg.Open(c4d.DLG_TYPE_ASYNC)
main.dlg = dlg
if __name__=='__main__':
main()
Dernière modification par xs_yann ; 04/12/2015 à 10h44.
Merci xs_yann pour ce complément qui me sera très utile !
Question de débutant en python.
*args
C'est comme en C sa correspond à un pointeur? et **var à une référence?
SDK Specialist
MAXON Computer GmbH
Non c'est une autre notation en python.
En fait ça a deux usages (qui fonctionnent sur le même principe) :
Le premier sert à passer des listes ou dictionnaires en paramètres de fonction :
Liste :
Dictionnaire :Code PHP:
def toto(a, b, c):
print a, b
params = [1, 2, 3]
toto(*params)
Combiné :Code PHP:
params = {'c': 3, 'b': 2}
params['a'] = 1
toto(**params)
Le deuxième à recevoir des arguments multiple dans une fonction :Code PHP:
params1 = [1, 2]
params2 = {'c': 3}
toto(*params1, **params2)
Argument anonymes :
Argument nommés :Code PHP:
def tata(*args):
for arg in args:
print arg
tata(1, 2, 3, 4, 5)
Et tu peux te servir de ça pour encapsuler une fonction et l'appeler 'sans connaître' ses paramètres (et ça évite d'avoir à réécrire les paramètres par défaut) :Code PHP:
def titi(*args, **kwargs):
for arg in args:
print arg
for k,v in kwargs.iteritems():
print k, v
titi(1, 2, 3, a=4, b=5)
C'est ça que j'utilise pour surcharger GeDialog.Open et appeler la méthode de la classe parente avec les arguments passés de manière transparente.Code PHP:
def foobar(param1, param2='abc', param3='toto', param4=12345, param5=20):
print param1, param2, param3, param4, param5
def wrapper(*args, **kwargs):
print 'wrapper'
foobar(*args, **kwargs)
wrapper('foo')
wrapper('foo', 'bar')
Merci pour l'info effectivement ça peux servir !
SDK Specialist
MAXON Computer GmbH