タイトルが異なりますが、こちらの続きです。
TSMファイル6 - C#ATIA
何とか、この不具合のような状況を回避策を見付けてから
宿題に取り掛かりたいです。
コマンドを自作しダイアログを表示させる場ですが、
Helpのサンプルコードを見ても結構長いです。
そこで何も処理は行いませんが、最低限なコードを作成しました。
#FusionAPI_python_script #Author-kantoku #Description-CommandTest import adsk.core, adsk.fusion, traceback _app = None _ui = None _handlers = [] class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler): def __init__(self): super().__init__() def notify(self, args): try: cmd = adsk.core.Command.cast(args.command) inputs = cmd.commandInputs onDestroy = MyCommandDestroyHandler() cmd.destroy.add(onDestroy) _handlers.append(onDestroy) selectionInput = inputs.addSelectionInput('HOGE', 'PIYO', 'HUGA') print('piyo') #ここにブレークポイント except: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) class MyCommandDestroyHandler(adsk.core.CommandEventHandler): def __init__(self): super().__init__() def notify(self, args): try: adsk.terminate() except: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def run(context): try: global _app, _ui _app = adsk.core.Application.get() _ui = _app.userInterface cmdDef = _ui.commandDefinitions.itemById('HOGE') if not cmdDef: cmdDef = _ui.commandDefinitions.addButtonDefinition('HOGE', 'PIYO', 'HUGA') onCommandCreated = MyCommandCreatedHandler() cmdDef.commandCreated.add(onCommandCreated) _handlers.append(onCommandCreated) cmdDef.execute() adsk.autoTerminate(False) except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
今の知識の範囲で最低限にしたつもりですが、結構長いです。
実行するとこんな感じです。
要素の選択とか出来ますが、OKを押しても何も起きません。
取りあえず、OKかキャンセルでダイアログを閉じます。
続いてMyCommandCreatedHandlerクラスのコメントを付けた部分に
ブレークポイントを設置して、デバッグを実行します。
class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler): ・・・ selectionInput = inputs.addSelectionInput('HOGE', 'PIYO', 'HUGA') print('piyo') #ここにブレークポイント ・・・
この様な状態で、赤印部を押しデバッグを終了します。
Fusion360上では、先程同様のダイアログが出ていますが、これも
終了させます。
問題は次です。再度デバッグを実行します。すると以下の状態に
なります。
残念。「選択」が2個になってしまいました。
しかし、問題の再現は出来ました。
エントリーポイントのrun関数をよく見ると
・・・ #自作commandDefinitionを取得 cmdDef = _ui.commandDefinitions.itemById('HOGE') if not cmdDef: #見付からない場合は作成 cmdDef = _ui.commandDefinitions.addButtonDefinition('HOGE', 'PIYO', 'HUGA') #自作commandDefinitionにハンドル類を登録 onCommandCreated = MyCommandCreatedHandler() cmdDef.commandCreated.add(onCommandCreated) _handlers.append(onCommandCreated) ・・・
まず、commandDefinitionをIDから取得し、見つからない場合は
作成しています。
その後commandDefinitionにハンドル類を登録し自作コマンドを
作成・実行しています。
この手順は、Helpのサンプル等で必ず記載されています。
色々と試した結果、この部分の処理方法が上記の不具合原因だと
わかりました。
意図的にデバッグを終了したり、エラーが出て終了した場合は、
自作コマンドの破棄が正しく行われない事が原因だと言う事の
様な為、サンプルに見られる方法の逆を行う様に修正しました。
・・・ def run(context): try: global _app, _ui _app = adsk.core.Application.get() _ui = _app.userInterface cmdDef = _ui.commandDefinitions.itemById('HOGE') if cmdDef: cmdDef.deleteMe() cmdDef = _ui.commandDefinitions.addButtonDefinition('HOGE', 'PIYO', 'HUGA') onCommandCreated = MyCommandCreatedHandler() cmdDef.commandCreated.add(onCommandCreated) _handlers.append(onCommandCreated) cmdDef.execute() adsk.autoTerminate(False) except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
commandDefinitionをIDから取得し、見つかった場合は一度破棄して
しまい、毎回新たに作成してしまいます。
これにより、毎回クリーンな状態で自作コマンドが作成され
不具合的な表示を避ける事が出来るようになりました。
他にも方法があると思うし、これはこれで良くない部分もあるのは
確かなのですが(ダイアログ表示中に再度コマンドを実行するとエラー)
一番簡単な対処方法かなぁ と思ってます。