Salvo Dragotta
Salvo Dragotta

Reputation: 13

RPS, windows Form & Revit API (Python)

I've been trying to build a form to create and delete Revit print Sets.

I've 2 main issues:

1) I'm able to create a print set but I cannot access its content unless I restart the Form. I get the errors below (depending if I'm defining the view_set variable or not)

List_object_has_no_attribute_Views

Local_variable_referenced_before_assignment

This is the code of the function to display the sheets of the selected Print Set

def DisplaySheetsInSet (self, sender, args):        

    self.curItem = CurrentSetsListBox.SelectedItem

    PrintSetForm_Load

    try:
        view_set=[]
        for i in PrintSetForm.ViewSets:

            if i.Name == str(self.curItem):
                view_set = i
            else:
                continue

        Sheets=[sheet.Name for sheet in view_set.Views]

        SheetsLb.BeginUpdate()
        SheetsLb.Items.Clear()

        for sheet in Sheets:        
            SheetsLb.Items.Add(sheet) 

        SheetsLb.EndUpdate()

    except Exception as e:
        popup (str(e)

2) I'm able to delete print sets once. If I try do delete another one I get the following error and I need to restart the form ( code for the function that deletes the print sets shown below)

The_referenced_object_is_not_valid

def DelPrintSet(self, sender, args):

        self.curItem = CurrentSetsListBox.SelectedItems

        t = Transaction (doc, 'Delete printset')
        t.Start()

        for viewset in PrintSetForm.ViewSets:
            if viewset.Name in [str(item) for item in self.curItem]:
                doc.Delete(viewset.Id)
                doc.Regenerate()
            else:
                continue                

        self.Refresh()

        UpdateSetNames(CurrentSetsListBox)      

        t.Commit()      

I've tried to build a function to restart/refresh the Form but it doesn't work (code below):

global PrintSetForm_Load
def PrintSetForm_Load(self, sender):

Application.Exit()
Application.Restart()
#self.Refresh()
#self.ResetBindings()
#self.ActiveForm.Close()    
sd = PrintSetForm()
sd.ShowDialog()

This gif shows the form in action:

Manage Print Sets

Any ideas or suggestions?

Thank you.

3) If I try to populate the SheetsLb with a DataSource, just the first set clicked is shown.

Sheets=[sheet.Name for sheet in view_set.Views]
SheetNumber=[sheet.get_Parameter(BuiltInParameter.SHEET_NUMBER).AsString() for sheet in view_set.Views]

SheetsLb.BeginUpdate()
SheetsLb.DataSource =  None
SheetsLb.Items.Clear()
UpdatedList=[]
for number,name in zip(SheetNumber,Sheets):
    UpdatedList.append(number+" - "+ name + " [ ] ")

SheetsLb.DataSource=UpdatedList

SheetsLb.EndUpdate()    

Upvotes: 1

Views: 377

Answers (2)

Callum
Callum

Reputation: 588

1) See if this works:

  • It would be worth checking that there is something selected in self.viewSetsLb. Ive added a check to the code below
  • The view_set variable could be initialised as a boolean instead of a list
  • Using break in the for loop keeps things a little snappier
  • Ive used the more pythonic for view in PrintSetForm.viewSets rather than for i in PrintSetForm.viewSets - keeping it nice and clear

This code works for me:

self.curItem = self.viewSetsLb.SelectedItem 

if not self.viewSetsLb.SelectedItem:
    print 'No Printset selected!'
    return

view_set = False

for view in PrintSetForm.viewSets:
    if view.Name == str(self.curItem):
        view_set = view
        break
    else:
        continue

Sheets=[sheet.Name for sheet in view_set.Views]

self.sheetsLb.BeginUpdate()
self.sheetsLb.Items.Clear()     
for sheet in Sheets:        
    self.sheetsLb.Items.Add(sheet)      
self.sheetsLb.EndUpdate()

2) Its because the data in your PrintSetForm.ViewSets list is out of date. Every time you change something (ie delete a viewset), repopulate this list:

PrintSetForm.ViewSets = FilteredElementCollector(doc).OfClass(ViewSheetSet).ToElements()

Also, you shouldnt need to build a refresh button, perhaps have a class function that repopulates the Printset list and ListBox, and clears the Sheet ListBox that you call after every action?

Sounds like youre having fun mate!

Upvotes: 1

Jeremy Tammik
Jeremy Tammik

Reputation: 8294

It sounds as if you have an issue with the scoping and lifetime of variables. For instance, some variables may have a lifetime limited to the form display, and therefore cannot be accessed after the form is closed. You could change the lifetime of these variables, e.g., by making them static class variables instead of local instance variables. I suggest you read up on .net static class variable scope.

Upvotes: 0

Related Questions