Boutique Cinema 4D
Affichage des résultats 1 à 6 sur 6

Discussion: Scripts python et dialogues asynchrone

  1. #1
    Pilier Avatar de oli_d
    Date d'inscription
    avril 2004
    C4D version
    Autre
    OS
    MacOS X
    Messages
    707

    Scripts python et dialogues asynchrone

    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 :
    Code PHP:

    import c4d

    class MonDlgc4d.gui.GeDialog):
        
        
    def CreateLayout(self):
            
    self.AddStaticText(1000c4d.BFH_SCALE|c4d.BFV_SCALEinitw=100inith=20,name 'Hello world !')        
            return 
    True

    def main
    ():
        
    dlg MonDlg()
        
    dlg.Open(c4d.DLG_TYPE_ASYNC)

    if 
    __name__=='__main__':
        
    main() 
    Si on lance le script et que l'on essaie de modifier la taille de la fenêtre, le contenu disparaît
    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:
    Code PHP:
    import c4d

    class MonDlgc4d.gui.GeDialog):
        
        
    def CreateLayout(self):
            
    self.AddStaticText(1000c4d.BFH_SCALE|c4d.BFV_SCALEinitw=100inith=20,name 'Hello world !')        
            return 
    True

    def main
    ():
        global 
    dlg
        dlg 
    MonDlg()
        
    dlg.Open(c4d.DLG_TYPE_ASYNC)

    if 
    __name__=='__main__':
        
    main() 
    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 MonDlgc4d.gui.GeDialog):
        
        
    def CreateLayout(self):
            
    self.AddStaticText(1000c4d.BFH_SCALE|c4d.BFV_SCALEinitw=100inith=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 à 08h43.

  2. #2
    Pilier Avatar de xs_yann
    Date d'inscription
    février 2005
    C4D version
    R19 Studio
    OS
    Mac OS X 10.13
    Messages
    1 990
    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 :
    Code PHP:
    import c4d

    class Dialog(c4d.gui.GeDialog):
        
        
    __dialogs = []
        
        
    def CreateLayout(self):
            
    self.AddStaticText(1000c4d.BFH_SCALE c4d.BFV_SCALEinitw=100inith=20name='Hello world !')        
            return 
    True
        
        def Open
    (self, *args, **kwargs):
            
    super(Dialogself).Open(*args, **kwargs)
            
    self.__dialogs.append(self)

                
    def main():
        
    dlg Dialog()
        
    dlg.Open(c4d.DLG_TYPE_ASYNC)

    if 
    __name__=='__main__':
        
    main() 
    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):
         
        
    def CreateLayout(self):
            
    self.AddStaticText(1000c4d.BFH_SCALE c4d.BFV_SCALEinitw=100inith=20name='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 à 11h44.

  3. #3
    Pilier Avatar de oli_d
    Date d'inscription
    avril 2004
    C4D version
    Autre
    OS
    MacOS X
    Messages
    707
    Merci xs_yann pour ce complément qui me sera très utile !

  4. #4
    Pilier Avatar de gr4ph0s
    Date d'inscription
    mai 2013
    C4D version
    R16 Studio
    OS
    win 7 X64
    Messages
    964
    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

  5. #5
    Pilier Avatar de xs_yann
    Date d'inscription
    février 2005
    C4D version
    R19 Studio
    OS
    Mac OS X 10.13
    Messages
    1 990
    Citation Envoyé par gr4ph0s Voir le message
    Question de débutant en python.
    *args

    C'est comme en C sa correspond à un pointeur? et **var à une référence?

    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 :
    Code PHP:
    def toto(abc):
        print 
    ab

    params 
    = [123]
    toto(*params
    Dictionnaire :
    Code PHP:
    params = {'c'3'b'2}
    params['a'] = 1
    toto
    (**params
    Combiné :
    Code PHP:
    params1 = [12]
    params2 = {'c'3
    toto(*params1, **params2
    Le deuxième à recevoir des arguments multiple dans une fonction :

    Argument anonymes :
    Code PHP:
    def tata(*args):
        for 
    arg in args:
            print 
    arg

    tata
    (12345
    Argument nommés :
    Code PHP:
    def titi(*args, **kwargs):
        for 
    arg in args:
            print 
    arg
        
    for k,v  in kwargs.iteritems():
            print 
    kv

    titi
    (123a=4b=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 foobar(param1param2='abc'param3='toto'param4=12345param5=20):
        print 
    param1param2param3param4param5
        
    def wrapper
    (*args, **kwargs):
        print 
    'wrapper'
        
    foobar(*args, **kwargs)
        
    wrapper('foo')
    wrapper('foo''bar'
    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.

  6. #6
    Pilier Avatar de gr4ph0s
    Date d'inscription
    mai 2013
    C4D version
    R16 Studio
    OS
    win 7 X64
    Messages
    964
    Merci pour l'info effectivement ça peux servir !
    SDK Specialist
    MAXON Computer GmbH

Discussions similaires

  1. Petits Scripts, Python
    Par ksaa dans le forum Programmation
    Réponses: 51
    Dernier message: 29/09/2012, 14h12
  2. Python : Boîte de dialogue asynchrone
    Par César Vonc dans le forum Programmation
    Réponses: 2
    Dernier message: 20/04/2012, 23h33
  3. Python Scripts phidek
    Par phidek dans le forum Programmation
    Réponses: 8
    Dernier message: 22/06/2011, 19h41
  4. Scripts divers python by oli_d
    Par oli_d dans le forum Programmation
    Réponses: 48
    Dernier message: 14/05/2011, 09h37
  5. C++ : boîte de dialogue
    Par Glloq dans le forum Programmation
    Réponses: 6
    Dernier message: 31/03/2011, 00h10

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •  
Mediaworks - Logiciels 3D | Design Internet - Creation site internet