Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • docs/extend-widgets/rst/contextsettings.rst

    r11408 r11593  
    2121selecting a subset of attributes and the class attributes (note that a 
    2222better widget for this task is already included in your Orange 
    23 instalation). 
     23installation). 
    2424 
    2525.. image:: attributesampler.png 
     
    2929somehow store the user's selection. 
    3030 
    31 Here's the widget's :obj:`__init__` function. 
    32  
    33 Part of :download:`OWAttributeSampler.py <OWAttributeSampler.py>`:: 
    34  
    35     def __init__(self, parent=None, signalManager=None): 
    36         OWWidget.__init__(self, parent, signalManager, 'AttributeSampler') 
    37  
    38         self.inputs = [("Examples", ExampleTable, self.dataset)] 
    39         self.outputs = [("Examples", ExampleTable)] 
    40  
    41         self.icons = self.createAttributeIconDict() 
    42  
    43         self.attributeList = [] 
    44         self.selectedAttributes = [] 
    45         self.classAttribute = None 
    46         self.loadSettings() 
    47  
    48         OWGUI.listBox(self.controlArea, self, "selectedAttributes", "attributeList", box="Selected attributes", selectionMode = QListWidget.ExtendedSelection) 
    49         OWGUI.separator(self.controlArea) 
    50         self.classAttrCombo = OWGUI.comboBox(self.controlArea, self, "classAttribute", box="Class attribute") 
    51         OWGUI.separator(self.controlArea) 
    52         OWGUI.button(self.controlArea, self, "Commit", callback = self.outputData) 
    53  
    54         self.resize(150,400) 
     31Here's the widget's :func:`__init__` function. 
     32 
     33Part of :download:`OWAttributeSampler.py <OWAttributeSampler.py>` 
     34 
     35.. literalinclude:: OWAttributeSampler.py 
     36   :pyobject: OWAttributeSampler.__init__ 
    5537 
    5638Note that we are strictly using controls from OWGUI. As for the 
     
    6446 
    6547When the widget gets the data, a function :obj:`dataset` is 
    66 called. 
    67  
    68 Part of :download:`OWAttributeSampler.py`:: 
     48called:: 
    6949 
    7050    def dataset(self, data): 
     
    8565 
    8666 
    87     def outputData(self): 
    88         if not self.data: 
    89             self.send("Examples", None) 
    90         else: 
    91             newDomain = orange.Domain([self.data.domain[i] for i in self.selectedAttributes], self.data.domain[self.classAttribute]) 
    92             newData = orange.ExampleTable(newDomain, self.data) 
    93             self.send("Examples", newData) 
     67.. literalinclude:: OWAttributeSampler.py 
     68   :pyobject: OWAttributeSampler.outputData 
     69 
    9470 
    9571Nothing special here (yet). We fill the list box, deselect all 
     
    11086exist in the actual domain at all. 
    11187 
    112 To make the setting dependent on the context, we put :: 
    113  
    114     contextHandlers = {"": DomainContextHandler("", [ 
    115             ContextField("classAttribute", DomainContextHandler.Required), 
    116             ContextField("attributeList", DomainContextHandler.List + 
    117                                           DomainContextHandler.SelectedRequired, 
    118                          selected="selectedAttributes")])} 
     88To make the setting dependent on the context, we put 
     89 
     90.. literalinclude:: OWAttributeSampler.py 
     91   :start-after: # ~start context handler~ 
     92   :end-before: # ~end context handler~ 
    11993 
    12094at the same place where we usually declare :obj:`settingsList`. 
     
    156130(:obj:`DomainContextHandler.Optional`); sometimes certain 
    157131attribute doesn't really matter, so if it is present in the domain, 
    158 it's gonna be used, otherwise not. And for the list, we could say 
     132it's going to be used, otherwise not. And for the list, we could say 
    159133:obj:`DomainContextHandler.List + DomainContextHandler.Required` 
    160134in which case all the attributes on the list would be required for the 
    161135domain to match. 
    162136 
    163 The default flag is :obj:`DomainContextHandler.Required`, and there are other shortcuts for declaring the context, too. The above code could be simplified as :: 
    164  
    165     contextHandlers = {"": DomainContextHandler("", [ 
    166             "classAttribute", 
    167             ContextField("attributeList", DomainContextHandler.SelectedRequiredList, 
    168                          selected="selectedAttributes")])} 
     137The default flag is :obj:`DomainContextHandler.Required`, and there 
     138are other shortcuts for declaring the context, too. The above code could 
     139be simplified as :: 
     140 
     141    contextHandlers = { 
     142        "": DomainContextHandler( 
     143            "", 
     144            ["classAttribute", 
     145             ContextField("attributeList", 
     146                          DomainContextHandler.SelectedRequiredList, 
     147                          selected="selectedAttributes")])} 
    169148 
    170149Why the dictionary and the empty string as the key? A widget can 
     
    186165function :obj:`dataset` 
    187166 
    188 Part of :download:`OWAttributeSampler.py`:: 
    189  
    190     def dataset(self, data): 
    191         self.closeContext() 
    192      
    193         self.classAttrCombo.clear() 
    194         if data: 
    195             self.attributeList = [(attr.name, attr.varType) for attr in data.domain] 
    196             self.selectedAttributes = [] 
    197             for attrName, attrType in self.attributeList: 
    198                 self.classAttrCombo.addItem(self.icons[attrType], attrName) 
    199             self.classAttribute = 0 
    200         else: 
    201             self.attributeList = [] 
    202             self.selectedAttributes = [] 
    203             self.classAttrCombo.addItem("") 
    204      
    205         self.openContext("", data) 
    206      
    207         self.data = data 
    208         self.outputData() 
    209  
    210 We added only two lines. First, before you change any controls in the widget, you need to call :obj:`self.closeContext` (the function has an optional argument, the context name, but since we use the default name, an empty string, we can omit it). This reads the data from the widget into the stored context. Then the function proceeds as before: the controls (the list box and combo box) are filled in as if there were no context handling (this is important, so once again: widget should be set up as if there were not context dependent settings). When the controls are put in a consistent state, we call :obj:`self.openContext`. The first argument is the context name and the second is the object from which the handler reads the context. In case of :obj:`DomainContextHandler` this can be either a domain or the data. :obj:`openContext` will make the context handler search through the stored context for the one that (best) matches the data, and if one is find the widget's state is set accordingly (that is, the list boxes are filled, attributes in it are selected etc.). If no context is found, a new context is established and the data from widget is copied to the context. 
     167.. literalinclude:: OWAttributeSampler.py 
     168   :pyobject: OWAttributeSampler.dataset 
     169 
     170We added only two lines. First, before you change any controls in 
     171the widget, you need to call :obj:`self.closeContext` (the function 
     172has an optional argument, the context name, but since we use the 
     173default name, an empty string, we can omit it). This reads the 
     174data from the widget into the stored context. Then the function 
     175proceeds as before: the controls (the list box and combo box) 
     176are filled in as if there were no context handling (this is 
     177important, so once again: widget should be set up as if there 
     178were not context dependent settings). When the controls are put 
     179in a consistent state, we call :obj:`self.openContext`. The first 
     180argument is the context name and the second is the object from 
     181which the handler reads the context. In case of 
     182:obj:`DomainContextHandler` this can be either a domain or the 
     183data. :obj:`openContext` will make the context handler search 
     184through the stored context for the one that (best) matches the 
     185data, and if one is find the widget's state is set accordingly 
     186(that is, the list boxes are filled, attributes in it are selected 
     187etc.). If no context is found, a new context is established and the 
     188data from widget is copied to the context. 
    211189 
    212190What can be stored as a context dependent setting? Anything, even 
Note: See TracChangeset for help on using the changeset viewer.