Updating UI command dialog

Updating UI command dialog

brad.bylls
Collaborator Collaborator
1,264 Views
4 Replies
Message 1 of 5

Updating UI command dialog

brad.bylls
Collaborator
Collaborator

Having trouble updating the command dialog from my script.

I have taken the SpurGear script and cannibalized it for creating a bolt w/a cut body.

When the user selects a screw size from the drop down, the UI dialog does not update.

 

# Author-Brad Bylls and many thanks to Brian Ekins and Autodesk
# for the great Spur Gear script from which this was taken.

# Description-Creates a SHCS w/Cut Body component.

# THIS PROGRAM IS PROVIDED "AS IS" AND WITH ALL FAULTS. I SPECIFICALLY
# DISCLAIM ANY IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.
# I DO NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR FREE.

import adsk.core, adsk.fusion, traceback
import math, os

# Globals
_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)
strUnits = ''

global strBoltBodyLength, strBoltClearanceLength, strBoltBodyDiam, strBoltHeadDiam, strBoltHeadHeight, \
strBoltHexSize, strBoltHeadFillet, strBoltTapDrill, strThreadEngage, strErrMessage
global numBoltBodyLength, numBoltClearanceLength, numBoltBodyDiam, numBoltHeadDiam, numBoltHeadHeight, \
numBoltHexSize, numBoltHeadFillet, numBoltTapDrill, numThreadEngage

# Command inputs
strSelectScrewSize = adsk.core.DropDownCommandInput.cast(None)
strBoltBodyLength = adsk.core.ValueCommandInput.cast(None)
strBoltClearanceLength = adsk.core.ValueCommandInput.cast(None)
strBoltBodyDiam = adsk.core.TextBoxCommandInput.cast(None)
strBoltHeadDiam = adsk.core.TextBoxCommandInput.cast(None)
strBoltHeadHeight = adsk.core.TextBoxCommandInput.cast(None)
strBoltHexSize = adsk.core.TextBoxCommandInput.cast(None)
strBoltHeadFillet = adsk.core.TextBoxCommandInput.cast(None)
strBoltTapDrill = adsk.core.TextBoxCommandInput.cast(None)
strThreadEngage = adsk.core.TextBoxCommandInput.cast(None)
strErrMessage = adsk.core.TextBoxCommandInput.cast(None)

_handlers = []


def run(context):
try:

<------------ Code -------------->

except:
if _ui:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


class BoltCommandDestroyHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()

def notify(self, args):
try:
eventArgs = adsk.core.CommandEventArgs.cast(args)

# when the command is done, terminate the script
# this will release all globals which will remove all event handlers
adsk.terminate()
except:
if _ui:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def getCommandInputValue(commandInput, unitType):
try:

<---------------- code -----------------.

except:
if _ui:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


# Event handler for the commandCreated event.
class BoltCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
def __init__(self):
super().__init__()

def notify(self, args):
try:
eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)

# Verify that a Fusion design is active.
des = adsk.fusion.Design.cast(_app.activeProduct)
if not des:
_ui.messageBox('A Fusion design must be active when invoking this command.')
return()

defaultUnits = des.unitsManager.defaultLengthUnits

# Set the units.
global strUnits, inputs
strUnits = 'in'

# Set default values for the UI dialog
strBoltBodyLength = '1.00'
strBoltBodyLengthAttrib = des.attributes.itemByName('CreateSHCS', 'boltBodyLength')
if strBoltBodyLengthAttrib:
strBoltBodyLength = strBoltBodyLengthAttrib.value

strBoltClearanceLength = '1.00'
strBoltClearanceLengthAttrib = des.attributes.itemByName('CreateSHCS', 'boltClearanceLength')
if strBoltClearanceLengthAttrib:
strBoltClearanceLength = strBoltClearanceLengthAttrib.value

strBoltBodyDiam = '.25'
strBoltBodyDiamAttrib = des.attributes.itemByName('CreateSHCS', 'boltBodyDiam')
if strBoltBodyDiamAttrib:
strBoltBodyDiam = strBoltBodyDiamAttrib.value

strBoltHeadDiam = '.375'
strBoltHeadDiamAttrib = des.attributes.itemByName('CreateSHCS', 'boltHeadDiam')
if strBoltHeadDiamAttrib:
strBoltHeadDiam = strBoltHeadDiamAttrib.value

strBoltHeadHeight = '.25'
strBoltHeadHeightAttrib = des.attributes.itemByName('CreateSHCS', 'boltHeadHeight')
if strBoltHeadHeightAttrib:
strBoltHeadHeight = strBoltHeadHeightAttrib.value

strBoltHexSize = '.1875'
strBoltHexSizeAttrib = des.attributes.itemByName('CreateSHCS', 'boltHexSize')
if strBoltHexSizeAttrib:
strBoltHexSize = strBoltHexSizeAttrib.value

strBoltHeadFillet = '.014'
strBoltHeadFilletAttrib = des.attributes.itemByName('CreateSHCS', 'boltHeadFillet')
if strBoltHeadFilletAttrib:
strBoltHeadFillet = strBoltHeadFilletAttrib.value

strBoltTapDrill = '.204'
strBoltTapDrillAttrib = des.attributes.itemByName('CreateSHCS', 'boltTapDrill')
if strBoltTapDrillAttrib:
strBoltTapDrill = strBoltTapDrillAttrib.value

strBoltChamfer = str(float(strBoltBodyDiam) * .075)
strBoltChamferAttrib = des.attributes.itemByName('CreateSHCS', 'boltChamfer')
if strBoltChamferAttrib:
strBoltChamfer = strBoltChamferAttrib.value

strThreadEngage = '1.5'
strThreadEngageAttrib = des.attributes.itemByName('CreateSHCS', 'threadEngage')
if strThreadEngageAttrib:
strThreadEngage = strThreadEngageAttrib.value

cmd = eventArgs.command
cmd.isExecutedWhenPreEmpted = False
inputs = cmd.commandInputs

# Define the UI command dialog
inputs.addImageCommandInput(
'screwImage', '', 'Resources/SHCS-half.png')
strSelectScrewSize = inputs.addDropDownCommandInput('screwSize', '1/4-20', adsk.core.DropDownStyles.TextListDropDownStyle)
# Read the csv file.
filePath = os.path.dirname(os.path.realpath(__file__))
cnt = 0
fileCsv = open(filePath + '\\SHCS-IMPERIAL.csv')
for line in fileCsv:
# Get the values from the csv file.
screws = line.split(',')
strSelectScrewSize.listItems.add(screws[0], False)

strBoltBodyLength = inputs.addStringValueInput('boltBodyLength', 'Screw Length', strBoltBodyLength)

strBoltClearanceLength = inputs.addStringValueInput('boltClearanceLength', 'Clearance Length', strBoltClearanceLength)

strBoltBodyDiam = inputs.addTextBoxCommandInput('boltBodyDiam', 'Screw Diameter', strBoltBodyDiam, 1, True)

strBoltHeadDiam = inputs.addTextBoxCommandInput('boltHeadDiam', 'Head Diameter', strBoltHeadDiam, 1, True)

strBoltHeadHeight = inputs.addTextBoxCommandInput('boltHeadHeight', 'Head Height', strBoltHeadHeight, 1, True)

strBoltHexSize = inputs.addTextBoxCommandInput('boltHexSize', 'Hex Size', strBoltHexSize, 1, True)

strBoltTapDrill = inputs.addTextBoxCommandInput('boltTapDrill', 'Tap Drill', strBoltTapDrill, 1, True)

strBoltHeadFillet = inputs.addTextBoxCommandInput('boltHeadFillet', 'Head Fillet', strBoltHeadFillet, 1, True)

strErrMessage = inputs.addTextBoxCommandInput('errMessage', '', '', 2, True)
strErrMessage.isFullWidth = True

# Connect to the command related events.
onExecute = BoltCommandExecuteHandler()
cmd.execute.add(onExecute)
_handlers.append(onExecute)

onInputChanged = BoltCommandInputChangedHandler()
cmd.inputChanged.add(onInputChanged)
_handlers.append(onInputChanged)

onValidateInputs = BoltCommandValidateInputsHandler()
cmd.validateInputs.add(onValidateInputs)
_handlers.append(onValidateInputs)

onDestroy = BoltCommandDestroyHandler()
cmd.destroy.add(onDestroy)
_handlers.append(onDestroy)
except:
if _ui:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


# Event handler for the execute event.
class BoltCommandExecuteHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()

def notify(self, args):
try:

<-------------------- code --------------------->

except:
if _ui:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

# Event handler for the inputChanged event.
class BoltCommandInputChangedHandler(adsk.core.InputChangedEventHandler):
def __init__(self):
super().__init__()

def notify(self, args):
try:
eventArgs = adsk.core.InputChangedEventArgs.cast(args)
changedInput = eventArgs.input

global strUnits
if changedInput.id == 'screwSize':
strResult = inputs.itemById('screwSize').selectedItem.name

filePath = os.path.dirname(os.path.realpath(__file__))
cnt = 0
fileCsv = open(filePath + '\\SHCS-IMPERIAL.csv')
for line in fileCsv:
# Get the values from the csv file.
screws = line.split(',')

if screws[0] == strResult:
strBoltBodyDiam = screws[1]
strBoltHeadDiam = screws[2]               ## I think this is where the
strBoltHeadHeight = screws[3]           ## UI dialog should update values (not sure)
strBoltHexSize = screws[4]                  ## but it does not.
strBoltTapDrill = screws[5]
strBoltHeadFillet = screws[6]

numBoltBodyDiam = float(strBoltBodyDiam)
numBoltHeadDiam = float(strBoltHeadDiam)
numBoltHeadHeight = float(strBoltHeadHeight)
numBoltHexSize = float(strBoltHexSize)
numBoltTapDrill = float(strBoltTapDrill)
numBoltHeadFillet = float(strBoltHeadFillet)

# Update the body length value.
elif changedInput.id == 'boltBodyLength':
strBoltBodyLength = inputs.itemById('boltBodyLength').value

# Update the clearance length value.
elif changedInput.id == 'boltClearanceLength':
strBoltClearanceLength = inputs.itemById('boltClearanceLength').value

except:
if _ui:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

<----------------- more code below -------------------->

 

Full code attached if needed.

Thank you in advance.

Brad Bylls
0 Likes
Accepted solutions (2)
1,265 Views
4 Replies
Replies (4)
Message 2 of 5

chris.midgley
Enthusiast
Enthusiast
Accepted solution

Hi - There are a few problems that will need attention. First, there is a general issue overloading a single variable with two different meanings - that of the string of the item, and that of the control on the page.  For example, in this code...

 

    strBoltBodyDiam = '.25'
    strBoltBodyDiamAttrib = des.attributes.itemByName('CreateSHCS', 'boltBodyDiam')
    if strBoltBodyDiamAttrib:
        strBoltBodyDiam = strBoltBodyDiamAttrib.value

 

the variable strBoltBodyDiam refers to a string with the value you are managing.  Worth noting, strBoltBodyDiam is a global, which it likely should not be when used for this purpose.

 

However, later in the code you have this:

 

    strBoltBodyDiam = inputs.addTextBoxCommandInput('boltBodyDiam', 'Screw Diameter', strBoltBodyDiam, 1, True)

 

In this code, you are changing the definition of strBoltBodyDiam from the a string, to a TextBoxCommandInput object (see addTextBoxCommandInput)

 

Then later, in your notify handler of BoltCommandInputChangedHandler (and, a similar issue in BoltCommandExecuteHandler) you have:

 

strBoltBodyDiam = screws[1]

 

At this point in the code execution, this is likely that strBoltBodyDiam is actually the TextBoxCommandInput, and therefore should be something more like:

 

strBoltBodyDiam.text = screws[1]

 

except that first you should clean up this overloading of the variable.  I'd recommend:

 

1) Remove strBoltBodyDiam (and the others) from the global statement.  You do not need the strings to be global, and you want only one "truth" of a value, which should be from the control to ensure consistency

2) Add a new variable, such as inputBoltBodyDiam as your global (or better, make a class, but that is another discussion), and capture that when you call addTextBoxCommandInput.  Also you must declare it global within any function that changes it's value, which is the notify method in this case

3) Change the places that are referring to strBoltBodyDiam to be using inputBoltBodyDiam (etc), where the expectation is to update or manage the control on the page, versus a local variable

4) Eliminate your globals for numXXX, as they are not needed to be global

5) Eliminate the code that sets the numXXX values to themselves, as that does nothing

 

I've gone ahead and made all these changes, debugging your code along the way.  I fixed a bunch of type issues as well, but eventually ran into problems in your generation logic that I just commented out and have left for you.  But I think the basics are working now.

 

See attached for the source.

 

Good luck...

 

Chris

Message 3 of 5

brad.bylls
Collaborator
Collaborator
WOW.
Thanks Chris.
Being a newbie I appreciate all your help.
I will look at your code and hopefully make sense of what you have said in
your post.
Thanks again.

Brad
Brad Bylls
0 Likes
Message 4 of 5

brad.bylls
Collaborator
Collaborator

Figured out the stuff you did and left for me to fix.

Thank you so much.

Just working on the last time line group.

Brad Bylls
Message 5 of 5

chris.midgley
Enthusiast
Enthusiast
Accepted solution

Excellent - good to hear it is working for you, thanks for reporting back.

0 Likes