I need help building a form for selecting sheets.
Let´s start step by step, more questions to come.
name_attr (str,optional )
I want to use SheetNumber + Name as names for my items.
But the name_attr parameter lets me only use 1 parameter as name. How can I build my desired item name?
ops = SheetSet
res = forms.SelectFromList.show(ops,
multiselect=True,
name_attr='SheetNumber',
button_name='Select Sheet')
Groups
I´d like to group my sheets by sheetset.
While I get the concept of grouping in the following example, I don´t know how I can use this method with my lists.
>>> from pyrevit import forms
>>> ops = {'Sheet Set A': [viewsheet1, viewsheet2, viewsheet3],
... 'Sheet Set B': [viewsheet4, viewsheet5, viewsheet6]}
>>> res = forms.SelectFromList.show(ops,
... multiselect=True,
... name_attr='Name',
... group_selector_title='Sheet Sets',
... button_name='Select Sheets')
I´d start like that:
Make a list of all sheetset names
Make a list of lists with the sheets
Zip lists together and use a for loop to somehow iterate through the lists and get my desired opt
But I´m pretty shure this is wrong so I don´t even try. Would this even work with elements like sheets?
Or do I have to use this method if I want to group sheets and get the selected sheets as output?
>>> from pyrevit import forms
>>> class MyOption(forms.TemplateListItem):
... @property
... def name(self):
... return '{} - {}{}'.format(self.item.SheetNumber,
... self.item.SheetNumber)
>>> ops = [MyOption('op1'), MyOption('op2', True), MyOption('op3')]
>>> res = forms.SelectFromList.show(ops,
... multiselect=True,
... button_name='Select Item')
>>> [bool(x) for x in res] # or [x.state for x in res]
[True, False, True]
Take a look at the pyrevit forms.select_sheets() function. It may provide all the functionality you need, or if it doesn’t, you can dissect the code and recreate something custom.
The code for select_Sheets also uses the standard SelectFromList form and it does not even use the optional name_attr. So I´m afraid that doesn´t help me.
Edit: Oh, you are right , the select_sheets form relly uses sheetnumber+sheetname, but i don´t know why.
I tried if it works if just don´t use the optional name_attr parameter, but that doesn´t work:
If you’re passing an object (not just a text string) into the form, you have to either define the name_attr (can only be one attribute) or wrap those objects in a template list item that uses a ‘name’ property.
class MyOptionSheet(forms.TemplateListItem):
@property
def name(self):
return '{}:{} - {}'.format(self.item.ViewType,
self.item.Name,
self.item.SheetNumber)
ops = [MyOptionSheet(x) for x in sheets if not x.IsPlaceholder]
I tried my best but I´m still having trouble with the grouping.
My current result is, that the group names are correct, but if I select a group nothing happens. There are always all sheets displayed.
I’m not grouping by the standard sheetsets like the select-sheets form does, I want to group by a sheet parameter (project browser sorting level). This is why i made a list of the unique parameters and a list of sheet lists by this parameter.
def Sheets():
Sheets = FilteredElementCollector(doc).OfClass(ViewSheet).ToElements()
return Sheets
def SheetSets():
SheetSets = []
for s in Sheets:
paravalue = s.LookupParameter(BrowserSortParameter).AsString()
if paravalue not in SheetSets:
SheetSets.append(paravalue)
return SheetSets
def SheetsBySheetSet():
outlist = []
for SheetSet in SheetSets:
outlist2 = []
for Sheet in Sheets:
paravalue = Sheet.LookupParameter(BrowserSortParameter).AsString()
if paravalue == SheetSet:
outlist2.append(Sheet)
outlist.append(outlist2)
return outlist
class MyOptionSheet(forms.TemplateListItem):
@property
def name(self):
return '{} - {}'.format(
self.item.SheetNumber,
self.item.Name)
BrowserSortParameter = BrowserSortParameter()
Sheets = Sheets()
SheetSets = SheetSets()
SheetsBySheetSet = SheetsBySheetSet()
ops = {}
AllSheets = []
AllSheets.extend([MyOptionSheet(x) for x in Sheets if not x.IsPlaceholder])
ops['All'] = AllSheets
for SheetSet in SheetSets:
sheets = []
for SheetBySheetSet in SheetsBySheetSet:
for s in SheetBySheetSet:
sheets.append(MyOptionSheet(s))
ops[SheetSet] = sheets
selectedSheets = forms.SelectFromList.show(ops, 'Title', multiselect=True)
I think my problem is that I use the basic sheets list for the options:
ops = {}
AllSheets = []
AllSheets.extend([MyOptionSheet(x) for x in Sheets if not x.IsPlaceholder])
ops['All'] = AllSheets
Maybe Somehow I have to use the multi level list SheetsBySheetSet for the options?
Or am I doing something else wrong?
Go it working by ziping sheetsetnames and sheets together
for SheetSetName, SheetsBySheetSet in zip(SheetSetNames,SheetsBySheetSet):
sheets = []
for Sheet in SheetsBySheetSet:
sheets.append(MyOptionSheet(Sheet))
ops[SheetSetName] = sheets
But I have the next question.
The order of the groups is alphabetic, so in my case the “ALL” group comes after the groups that start with numbers, so pretty much at the bottom of the list.