Handling PF_OPTION in scripts is always a bit of a problem when there are many of them or long list of choices. Here is a technique that has several advantages:
Then you define your options as a list of (name,label) tuples, where name is how you refer to that option in the code, and
label is how it appears in the PF_OPTION or PF_RADIO widget:
To create the object that will carry the options, you call the function above, giving it a name, and the list of tuples, and keep the result is a variable:
The name as passed to the function is not too important, it just needs to be unique among your various set of options. What really counts is the name of the variable in which you keep the object.
In the resulting variable:
or your PF_RADIO like this:
To test an option in the code you just use its name:
or even:
Happy coding.
- No choice is ever referenced by its actual integer equivalent.
- The list of choices can be modified at will (insertions, reorders) without having to hunt the code for changes
- Choices and their labels cannot be "desynchronized" as would happen with parallel lists
- Code remains short
Code:
from collections import namedtuple
def createOptions(name,pairs):
# namedtuple('FooType',['OPTION1',...,'OPTIONn','labels','labelTuples']
optsclass=namedtuple(name+'Type',[symbol for symbol,label in pairs]+['labels','labelTuples'])
# FooType(0,..,n-1,['Option 1',...,'Option N'],[('Option 1',0),...,('Option N',n-1)])
opts=optsclass(*(
range(len(pairs))
+[[label for symbol,label in pairs]]
+[[(label,i) for i,(symbol,label) in enumerate(pairs)]]
))
return opts
Then you define your options as a list of (name,label) tuples, where name is how you refer to that option in the code, and
label is how it appears in the PF_OPTION or PF_RADIO widget:
Code:
[('NONE','None'),('LINKED','Linked layers'),('TEXT','Text layers')]
To create the object that will carry the options, you call the function above, giving it a name, and the list of tuples, and keep the result is a variable:
Code:
MergeOptions=createOptions('Merge',[('NONE','None'),('LINKED','Linked layers'),('TEXT','Text layers')])
The name as passed to the function is not too important, it just needs to be unique among your various set of options. What really counts is the name of the variable in which you keep the object.
In the resulting variable:
- The name of each tuple in the list is now an attribute: MergeOptions.NONE, MergeOptions.TEXT, MergeOptions.LINKED
- Thees attributes have the value of their index in the list: MergeOptions.NONE==0, MergeOptions.TEXT==1, MergeOptions.LINKED==2
- A labels attribute contains the list of labels: MergeOptions.labels==['None','Linked layers','Text layers']
- A labelTuples attribute contains the list of (labels,value) tuples: MergeOptions.labelsTuples==[('None',0),('Linked layers',1),('Text layers',2)]
Code:
(PF_OPTION, 'mergeLayers', 'Merge layers',MergeOptions.TEXT,MergeOptions.labels)
or your PF_RADIO like this:
Code:
(PF_RADIO, 'mergeLayers', 'Merge layers',MergeOptions.TEXT,MergeOptions.labelTuples)
To test an option in the code you just use its name:
Code:
if merge==MergeOptions.TEXT:
or even:
Code:
if merge in [MergeOptions.TEXT,MergeOptions.LINKED]:
Happy coding.