2

I am working on Dynamo for Revit. My code takes sheet numbers and other info, then creates labels and buttons for each IN element with a for loop. The GUI works fine and I have all the elements in place, but how do I tell each individual button to open a different sheet? See screenshot.

I need to understand the workflow, but here is the code of the loop if it helps:

# Create labels and buttons in loop
    y = 50
    a = 0
    for i in res:
        # creates section name label
        text = str(res[a][0])
        text = text[19:]
        text = text[:-1]
        labelSectionName = Label(Text = text)
        labelSectionName.Parent = self
        labelSectionName.Location = Point(gridColSecName,y)
        labelSectionName.Width = gridWidthSecName
        #labelSectionName.Height = 20
        
        # creates sheet number label
        text = str(res[a][2])
        labelSectionName = Label(Text = text)
        labelSectionName.Parent = self
        labelSectionName.Location = Point(gridColSheetNum,y)
        labelSectionName.Width = 50
        # create button for opening sheet
        button = Button()
        button.Parent = self
        button.Text = "Open Sheet"
        button.Location = Point(gridColButtSheet,y)
        # Register button event
        button.Click += self.?????????????????????????????????????

and this is the code for opening the sheet taken from another script

sheet = UnwrapElement(IN[0])
sheet_action=(IN[1])
output = []

if (str(sheet_action) == "Yes"):
    uidoc.RequestViewChange(sheet)
    output.append("ActiveView set to: " + sheet.Name)
else:
    pass

OUT = sheet_action

enter image description here

  • Generally speaking, when I deal with more than one button (pygame, or tkinter) what I do is create a dictionary that holds the button and its function. In your case, I would do exactly that and then cycle through the dictionary instead of using just using `range`. This is also said without any experience with Dynamo, but this is my 2 cents :) – Party-with-Programming Jan 21 '22 at 01:07
  • Thanks. How would you put the whole function into the dictionary? – Saverio Vasapollo Jan 21 '22 at 03:10
  • For a quick example: `buttonDict = {button1:button1Function, button2:button1Function, etc.}` (functions **without** parentheses). To call that function the easiest way would be to replace your `for i in res` with `for button in buttonDict:` (so that you don't need a list of `buttonDict` keys, as well, to access button functions), **then** `buttonDict[button](pass arguments for function)` – Party-with-Programming Jan 21 '22 at 04:17
  • maybe use `lambda` to assign function with parameters `Click += (lambda x=filename: function(x))`. It is common method used in other GUIs like `tkinter` or `PyQt`. BTW: And code in other script keep as `function` so you could use it many times with different parameter – furas Jan 21 '22 at 08:25
  • @Party-with-Programming Not sure about something: the dictionary needs to change every time according to the number of items (Section Name column in the screenshot), they can be 5, 12, 67 I do not know this is why I used a loop to create buttons. It looks to me that this dictionary is pre-created which will not work for me. – Saverio Vasapollo Jan 23 '22 at 22:44
  • If you wanted, you could use 2 lists (that way it can be however long required), one with `buttonObj` and the corresponding index on the second list is the function, and append as required. How about this for another option `button.Click = openSheetFunction(IN=res[a][2])`, using @furas suggestion? From what I gathered `res[a][2]` is the corresponding sheet (`# creates sheet number label text = str(res[a][2])`). – Party-with-Programming Jan 24 '22 at 04:55

0 Answers0