Changeset 11424:ccb4a5fac5e1 in orange


Ignore:
Timestamp:
03/22/13 14:15:15 (13 months ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
Message:

More fixes to Widgets Development documentation

Location:
docs/extend-widgets/rst
Files:
6 edited

Legend:

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

    r11049 r11424  
    1818Following is an example that defines two output channels:: 
    1919 
    20     self.outputs = [("Sampled Data", orange.ExampleTable), ("Learner", orange.Learner)] 
     20    self.outputs = [("Sampled Data", orange.ExampleTable), 
     21                    ("Learner", orange.Learner)] 
    2122 
    2223:obj:`self.outputs` should thus be a list of tuples, within 
     
    6263 
    6364    def receiveData(self, data): 
    64     # handle data in some way 
     65        # handle data in some way 
     66 
    6567 
    6668Any time our widget would receive a token, :obj:`receiveData` 
     
    7678deleted, Orange Canvas would automatically send :obj:`None` to 
    7779the receiving widget. Make sure your widget handles :obj:`None` 
    78 tokens appropriately!` 
     80tokens appropriately! 
    7981 
    8082There are cases when widget would like to know about the origin of 
     
    9395 
    9496   def learner(self, learnertoken, tokenid): 
    95    # handle learnertoken and tokeid in some way 
     97       # handle learnertoken and tokeid in some way 
    9698 
    9799Widgets such as :obj:`OWTestLearners` and alike use such 
     
    102104 
    103105    self.inputs = [("Data", orange.ExampleTable, self.maindata), 
    104                ("Additional Data", orange.ExampleTable, self.otherdata)] 
     106                   ("Additional Data", orange.ExampleTable, self.otherdata)] 
    105107 
    106108and we connect this widget in Orange Canvas to a sending widget 
    107109that has a single orange.ExampleTable output channel, Canvas would 
    108 bring up Set Channels dialog. There, a sending widget's channel could 
     110bring up *Set Channels* dialog. There, a sending widget's channel could 
    109111be connected to both receiving channels. As we would often prefer to 
    110112connect to a single (default) channel instead (still allowing user of 
     
    114116 
    115117    self.inputs = [("Data", orange.ExampleTable, self.maindata, Default), 
    116                ("Additional Data", orange.ExampleTable, self.otherdata)] 
     118                   ("Additional Data", orange.ExampleTable, self.otherdata)] 
  • docs/extend-widgets/rst/basics.rst

    r11408 r11424  
    4242categories. For instance, under windows and default settings, a 
    4343directory that stores all the widgets displayed in the Evaluate pane is 
    44 C:\Python23\Lib\site-packages\orange\OrangeWidgets\Evaluate. Figure 
     44*C:\\Python23\\Lib\\site-packages\\Orange\\OrangeWidgets\\Evaluate*. Figure 
    4545above shows that at the time of writing of this text there were five 
    4646widgets for evaluation of classifiers, and this is how my Evaluate 
     
    8080something like:: 
    8181 
    82     self.inputs = [("Test Data Set", ExampleTable, self.cdata), ("Learner", orange.Learner, self.learner, 0)] 
     82    self.inputs = [("Test Data Set", ExampleTable, self.cdata), 
     83                   ("Learner", orange.Learner, self.learner, 0)] 
    8384    self.outputs = [("Evaluation Results", orngTest.ExperimentResults)] 
    8485 
     
    9192now the following is important: 
    9293 
    93    -  Widgets are defined in a Python files. 
    94    - For Orange and Orange canvas to find them, they reside in subdirectories in OrangeWidgets directory of Orange installation. The name of the subdirectory matters, as this is the name of the widget category. Widgets in the same directory will be grouped in the same pane of widget toolbox in Orange Canvas. 
    95    - A file describing a widget starts with a header. This, given in sort of XMLish style, tells about the name, short description, location of an icon and priority of the widget. 
    96    - The sole role of priority is to specify the placement (order) of widgets in the Orange Canvas toolbox. 
    97    - Somewhere in the code (where we will learn later) there are two lines which tell which channels the widgets uses for communication. These, together with the header information, completely specify the widget as it is seen from the outside. 
     94   - Widgets are defined in a Python files. 
     95   - For Orange and Orange canvas to find them, they reside in subdirectories 
     96     in OrangeWidgets directory of Orange installation. The name of the 
     97     subdirectory matters, as this is the name of the widget category. Widgets 
     98     in the same directory will be grouped in the same pane of widget toolbox 
     99     in Orange Canvas. 
     100   - A file describing a widget starts with a header. This, given in sort of 
     101     XMLish style, tells about the name, short description, location of an 
     102     icon and priority of the widget. 
     103   - The sole role of priority is to specify the placement (order) of widgets 
     104     in the Orange Canvas toolbox. 
     105   - Somewhere in the code (where we will learn later) there are two lines 
     106     which tell which channels the widgets uses for communication. These, 
     107     together with the header information, completely specify the widget as it 
     108     is seen from the outside. 
    98109 
    99110Oh, by the way. Orange caches widget descriptions to achieve a faster 
  • docs/extend-widgets/rst/channels.rst

    r11408 r11424  
    2626Say we want to build a widget that takes a data set and test 
    2727various predictive modelling techniques on it. A widget has to have an 
    28 input data channel, and this we know how to deal with from our :doc:`previous <settings>` 
    29 lesson. But, somehow differently, we 
     28input data channel, and this we know how to deal with from our 
     29:doc:`previous <settings>` lesson. But, somehow differently, we 
    3030want to connect any number of widgets which define learners to our 
    3131testing widget. Just like in a schema below, where three different 
  • docs/extend-widgets/rst/graphing.rst

    r11408 r11424  
    3939    self.setGraphGrid() 
    4040 
    41 :obj:`OWGrap` is a convenience subclass of QwtPlot and is imported from OWGraph module. For the graph, we use :obj:`setAxisAutoScale` to 
     41:obj:`OWGrap` is a convenience subclass of QwtPlot and is imported from 
     42OWGraph module. For the graph, we use :obj:`setAxisAutoScale` to 
    4243request that the axis are automatically set in regard to the data that 
    4344is plotted in the graph. We plot the graph in using the following 
  • docs/extend-widgets/rst/owgui.rst

    r11408 r11424  
    3434`value` (required) 
    3535   String with the name of the master's attribute that synchronizes with the 
    36    state of the control (and vice-versa - when this attribute is changed, the control changes as well). This attribute should usually be also included the master's :obj:`settingsList`, so that it is automatically saved and retrieved. 
     36   state of the control (and vice-versa - when this attribute is changed, the 
     37   control changes as well). This attribute should usually be also included 
     38   the master's :obj:`settingsList`, so that it is automatically saved and 
     39   retrieved. 
    3740 
    3841`box` (default: None) 
    39    Indicates if there should be a box that is drawn around the control. If `box` is ``None``, no box is drawn; if it is a string, it is also used as box's name. If `box` is any other true value (such as ``True`` :), an unlabeled box is drawn. 
     42   Indicates if there should be a box that is drawn around the control. 
     43   If `box` is ``None``, no box is drawn; if it is a string, it is also used 
     44   as box's name. If `box` is any other true value (such as ``True`` :), 
     45   an unlabeled box is drawn. 
    4046 
    4147`callback` (default: None) 
     
    5157 
    5258`tooltip` (default: None) 
    53    A string that is displayed in a tooltip that appears when mouse is over the control. 
     59   A string that is displayed in a tooltip that appears when mouse is over the 
     60   control. 
    5461 
    5562`label` (default: None) 
     
    6067 
    6168`orientation` (default: "vertical") 
    62    When label is used, determines the relative placement of the label and the control. Label can be above the control, "vertical", or in the same line with control, "horizontal". Instead of "vertical" and "horizontal" you can also use ``True`` and ``False`` or 1 and 0, respectively. (Remember this as "vertical" being the usual order of controls in the widgets, so vertical is "true".) 
     69   When label is used, determines the relative placement of the label and the 
     70   control. Label can be above the control, "vertical", or in the same line 
     71   with control, "horizontal". Instead of "vertical" and "horizontal" you can 
     72   also use ``True`` and ``False`` or 1 and 0, respectively. (Remember this 
     73   as "vertical" being the usual order of controls in the widgets, so vertical 
     74   is "true".) 
    6375 
    6476`disabled` (default: False) 
     
    6678 
    6779`addSpace` (default: False) 
    68    If true, a space of 8 pixels is added after the widget by calling :func:`separator`. `addSpace` can also be an integer specifying the height of the added space. 
     80   If true, a space of 8 pixels is added after the widget by calling 
     81   :func:`separator`. `addSpace` can also be an integer specifying the height 
     82   of the added space. 
    6983 
    7084 
     
    7589This section describes the OWGUI wrappers for controls like check boxes, buttons 
    7690and similar. All the important Qt's controls can be constructed through this 
    77 functions. You should always use them instead of calling Qt directly, not only 
    78 because they are convenient, but also because they set up a lot of things that happen in behind. 
     91functions. 
     92 
     93.. 
     94   You should always use them instead of calling Qt directly, not only 
     95   because they are convenient, but also because they set up a lot of things 
     96   that happen in behind. 
    7997 
    8098 
     
    88106 
    89107   `disables` (default: []) 
    90       If the check box needs to disable some other controls they can be given in list  `disables`, e.g. ``disables=[someOtherCheckBox, someLineEdit]``. If the other control should be disabled when the checkbox is checked, do it like this: ``disables=[someOtherCheckBox, (-1, someLineEdit)]`` - now `someOtherCheckBox` will be enabled when this check box is checked, while `someLineEdit` will be enabled when the check box is unchecked. 
     108      If the check box needs to disable some other controls they can be given 
     109      in list  `disables`, e.g. ``disables=[someOtherCheckBox, someLineEdit]``. 
     110      If the other control should be disabled when the checkbox is checked, do 
     111      it like this: ``disables=[someOtherCheckBox, (-1, someLineEdit)]`` - now 
     112      `someOtherCheckBox` will be enabled when this check box is checked, 
     113      while `someLineEdit` will be enabled when the check box is unchecked. 
    91114 
    92115   `labelWidth` (default: None) 
     
    102125 
    103126   `valueType` (default: str) 
    104       A type into which the value is cast. 
     127      A type into which the `value` is cast. 
    105128 
    106129   `validator` (default: None) 
     
    152175 
    153176   `items` (default: []) 
    154       A list of combo box's items. Unlike most OWGUI, `items` have one Orange-specific quirk: its element can be either a string, in which case it is used as a label, or a tuple, where the first element is a label name and the last is the attribute type which is used to create an icon. Most attribute lists in Orange Widgets are constructed this way. 
     177      A list of combo box's items. Unlike most OWGUI, `items` have one 
     178      Orange-specific quirk: its element can be either a string, in which 
     179      case it is used as a label, or a tuple, where the first element is a 
     180      label name and the last is the attribute type which is used to create 
     181      an icon. Most attribute lists in Orange Widgets are constructed this way. 
    155182 
    156183   `sendSelectedValue` (default: 0) 
    157       If false, attribute `value` will be assigned the index of the selected item. Otherwise, it is assigned the currently selected item's label. 
     184      If false, attribute `value` will be assigned the index of the selected 
     185      item. Otherwise, it is assigned the currently selected item's label. 
    158186 
    159187   `control2attributeDict` (default: {}) 
    160       A dictionary for translating the item's label into `value`. It is used only is `sendSelectedValue` is true, and even then a label is translated only if an item with such a key is found in the dictionary; otherwise, label is written to `value` as it is.  
     188      A dictionary for translating the item's label into `value`. It is used 
     189      only is `sendSelectedValue` is true, and even then a label is translated 
     190      only if an item with such a key is found in the dictionary; otherwise, 
     191      label is written to `value` as it is. 
    161192 
    162193   `emptyString` (default: "") 
    163       Tells which combo box's item corresponds to an empty `value`. This is typically used when combo box's labels are attribute names and an item "(none)", which allows user to select no attribute. If we give ``emptyString="(none)"``, `value` will be an empty string when the user selects "(none)". This is equivalent to specifying ``control2attributeDict={"(none)": ""}`` (and is actually implemented like that), but far more convenient. 
     194      Tells which combo box's item corresponds to an empty `value`. This is 
     195      typically used when combo box's labels are attribute names and an item 
     196      "(none)", which allows user to select no attribute. If we give 
     197      ``emptyString="(none)"``, `value` will be an empty string when the user 
     198      selects "(none)". This is equivalent to specifying 
     199      ``control2attributeDict={"(none)": ""}`` (and is actually implemented 
     200      like that), but far more convenient. 
    164201 
    165202   `valueType` (default: str or unicode) 
    166       A function through which the currently selected item's label is converted prior to looking into `control2attributeDict`. Needed to convert Qt's QString. 
     203      A function through which the currently selected item's label is  
     204      converted prior to looking into `control2attributeDict`. Needed to 
     205      convert Qt's QString. 
    167206 
    168207 
     
    171210 
    172211This control, which might be the most complicated control in OWGUI, is a 
    173 sophisticated wrapper around QListBox. It's complexity arises from synchronization. 
     212sophisticated wrapper around QListBox. It's complexity arises from 
     213synchronization. 
    174214 
    175215 
     
    180220 
    181221   `labels` (required) 
    182       The name of master's attribute containing the list box's labels. Similar to `items` in combo box, list `labels` have one Orange-specific quirk: its element can be either a string, in which case it is used as a label, or a tuple, where the first element is a label name and the second can be either an icon on an integer, representing the attribute type which is used to create an icon. Most attribute lists in Orange Widgets are constructed this way. 
     222      The name of master's attribute containing the list box's labels. Similar 
     223      to `items` in combo box, list `labels` have one Orange-specific quirk: 
     224      its element can be either a string, in which case it is used as a label 
     225      or a tuple, where the first element is a label name and the second can 
     226      be either an icon on an integer, representing the attribute type which 
     227      is used to create an icon. Most attribute lists in Orange Widgets are 
     228      constructed this way. 
    183229 
    184230   `selectionMode` (default: QListWidget.SingleSelection) 
    185       Tells whether the user can select a single item (:obj:`QListWidget.SingleSelection`), multiple items (:obj:`QListWidget.MultiSelection`, :obj:`QListWidget.ExtendedSelection`) or nothing (:obj:`QListWidget.NoSelection`). 
    186  
    187    `value` is automatically cast to :obj:`OWGUI.ControlledList` (this is needed because the list should report any changes to the control, the list box; :obj:`OWGUI.ControlledList` is like an ordinary Python :obj:`list` except that it triggers synchronization with the list box at every change). 
    188  
    189    `labels` is only partially synchronized with the list box: if a new list is assigning to `labels` attribute, the list will change. If elements of the existing list are changed or added, the list box won't budge. You should never change the list, but always assign a new list (or reassign the same after it's changed). If the labels are stored in ``self.listLabels`` and you write ``self.listLabels[1]="a new label"``, the list box won't change. To trigger the synchronization, you should continue by ``self.listLabels = self.listLabels``. This may seem awkward, but by our experience a list of selected items is seldom changed changed "per-item", so we were too lazy to write the annoyingly complex backward callbacks. 
    190  
     231      Tells whether the user can select a single item 
     232      (:obj:`QListWidget.SingleSelection`), multiple items 
     233      (:obj:`QListWidget.MultiSelection`, :obj:`QListWidget.ExtendedSelection`) 
     234      or nothing (:obj:`QListWidget.NoSelection`). 
     235 
     236   `value` is automatically cast to :obj:`OWGUI.ControlledList` (this is 
     237   needed because the list should report any changes to the control, the list 
     238   box; :obj:`OWGUI.ControlledList` is like an ordinary Python :obj:`list` 
     239   except that it triggers synchronization with the list box at every change). 
     240 
     241   `labels` is only partially synchronized with the list box: if a new list 
     242   is assigning to `labels` attribute, the list will change. If elements of 
     243   the existing list are changed or added, the list box won't budge. You 
     244   should never change the list, but always assign a new list (or reassign 
     245   the same after it's changed). If the labels are stored in 
     246   ``self.listLabels`` and you write ``self.listLabels[1]="a new label"``, 
     247   the list box won't change. To trigger the synchronization, you should 
     248   continue by ``self.listLabels = self.listLabels``. This may seem awkward, 
     249   but by our experience a list of selected items is seldom changed changed 
     250   "per-item", so we were too lazy to write the annoyingly complex backward 
     251   callbacks. 
    191252 
    192253 
     
    205266****** 
    206267 
    207 A wrapper around QSlider that allows user setting a numerical value between the given bounds. 
     268A wrapper around QSlider that allows user setting a numerical value between 
     269the given bounds. 
    208270 
    209271.. function:: hSlider(widget, master, value[, box, minValue, maxValue, step, callback, labelFormat, ticks, divideFactor]) 
     
    214276 
    215277   `ticks` (default: 0) 
    216       If non-zero, it gives the interval between two ticks. The ticks will appear below the groove. 
     278      If non-zero, it gives the interval between two ticks. The ticks will 
     279      appear below the groove. 
    217280 
    218281   `labelFormat` (default: " %d") 
    219       Defines the look of the label on the righthand side of the slider. It has to contain one format character (like %d in the default), but can contain other text as well. 
     282      Defines the look of the label on the righthand side of the slider. It 
     283      has to contain one format character (like %d in the default), but can 
     284      contain other text as well. 
    220285 
    221286   `divideFactor` (default: 1.0) 
     
    226291******************* 
    227292 
    228 Check box with spin, or, essentially, a wrapper around 
    229 OWGUI.checkBox and OWGUI.spin. 
     293Check box with spin, or, essentially, a wrapper around OWGUI.checkBox and 
     294OWGUI.spin. 
    230295 
    231296.. function:: checkWithSpin(widget, master, label, min, max, checked, value[, posttext, step, tooltip, checkCallback, spinCallback, labelWidth]) 
     
    250315****** 
    251316 
    252 There are two functions for constructing labels. The first is a simple wrapper around QLabel which differs only in allowing to specify a fixed width without needing an extra line. Note that unlike most other OWGUI widgets, this one does not have the argument `master`. 
     317There are two functions for constructing labels. The first is a simple wrapper 
     318around QLabel which differs only in allowing to specify a fixed width without 
     319needing an extra line. Note that unlike most other OWGUI widgets, this one 
     320does not have the argument `master`. 
    253321 
    254322.. function:: widgetLabel(widget, label[, labelWidth]) 
    255323 
    256    The second is a label which can synchronize with values of master widget's attributes. 
     324   The second is a label which can synchronize with values of master widget's 
     325   attributes. 
    257326 
    258327.. function:: label(widget, master, label[, labelWidth]) 
     
    326395************************* 
    327396 
    328 Many widgets have a "Send" button (perhaps named "Apply", "Commit"...) accompanied with a check box "Send automatically", having the same effect as if the user pressed the button after each change. A well behaved widget cares to: 
     397Many widgets have a "Send" button (perhaps named "Apply", "Commit"...) 
     398accompanied with a check box "Send automatically", having the same effect as 
     399if the user pressed the button after each change. A well behaved widget cares 
     400to: 
    329401 
    330402* disable the button, when the check box is checked; 
    331 * when the user checks the check box, the data needs to be send (or the changes applied), but only if there is any pending change which has not been (manually) sent yet. 
    332  
    333 Programming this into every widget is annoying and error-prone; at the time when the function described here was written, not many widgets actually did this properly. 
     403* when the user checks the check box, the data needs to be send (or the 
     404  changes applied), but only if there is any pending change which has not been 
     405  (manually) sent yet. 
     406 
     407Programming this into every widget is annoying and error-prone; at the time 
     408when the function described here was written, not many widgets actually did 
     409this properly. 
    334410 
    335411.. function:: setStopper(master, sendButton, stopCheckbox, changedFlag, callback) 
     
    339415 
    340416   `stopCheckbox` 
    341       Check box that decides whether the changes are sent/commited/applied automatically. 
     417      Check box that decides whether the changes are sent/commited/applied 
     418      automatically. 
    342419 
    343420   `changedFlag` 
    344       The name of the `master`'s attribute which tells whether there is a change which has not been sent/applied yet. 
     421      The name of the `master`'s attribute which tells whether there is a 
     422      change which has not been sent/applied yet. 
    345423 
    346424   `callback` 
    347       The function that sends the data or applies the changes. This is typically the function which is also used as the `sendButton`'s callback. 
    348  
    349  
    350 :obj:`setStopper` is a trivial three lines long function which connects a few signals. Its true importance is in enforcing the correct procedure for implementing such button-check box combinations. 
     425      The function that sends the data or applies the changes. This is 
     426      typically the function which is also used as the `sendButton`'s callback. 
     427 
     428 
     429:obj:`setStopper` is a trivial three lines long function which connects a few 
     430signals. Its true importance is in enforcing the correct procedure for 
     431implementing such button-check box combinations. 
    351432 
    352433.. 
     
    354435 
    355436   Missing, where did it go? 
    356  
  • docs/extend-widgets/rst/settings.rst

    r11422 r11424  
    237237In general, the function should go like this. 
    238238 
    239 * Do any clean-up you need, but without clearing any of the settings that need to be saved. Scatter plot needs none. 
    240 * Call :obj:`self.closeContext`; this ensures that all the context dependent settings (e.g. attribute names from the list boxes) are remembered. 
    241 * Get the data (or whatever you do) and set the controls to some defaults as if there were no context retrieving mechanism. Scatter plot does it by calling :obj:`initAttrValues()` which assigns the first two attributes to the x and y axis and the class attribute to the color. At this phase, you shouldn't call any functions that depend on the settings, such as drawing the graph. 
    242 * Call :obj:`self.openContext` (more about the arguments later). This will search for a suitable context and assign the controls new values if one is found. If there is no saved context that can be used, a new context is created and filled with the default values that were assigned at the previous point. 
    243 * Finally, adjust the widget according to the retrieved controls. Scatter plot now plots the graph by calling :obj:`updateGraph`. 
    244  
    245  
    246 :obj:`closeContext` has an argument, the name of the context. If omitted (like above), the default name (:obj:`""`) is used. When opening the context, we give the name and some arguments on which the context depends. In case of :obj:`DomainContextHandler`, which scatter plot uses, we can give it a domain or any object that has a field :obj:`domain` containing a domain. Whether a saved context can be reused is judged upon the presence of attributes in the domain. 
    247  
    248 If the widget is constructed appropriately (that is, if it strictly uses OWGUI controls instead of the Qt's), no other administration is needed to switch the context. 
    249  
    250 Except for declaring the context settings, that is. Scatter plot has this just below the :obj:`settingsList`:: 
     239* Do any clean-up you need, but without clearing any of the settings that need 
     240  to be saved. Scatter plot needs none. 
     241* Call :obj:`self.closeContext()`; this ensures that all the context dependent 
     242  settings (e.g. attribute names from the list boxes) are remembered. 
     243* Get the data (or whatever you do) and set the controls to some defaults as 
     244  if there were no context retrieving mechanism. Scatter plot does it by 
     245  calling :obj:`initAttrValues()` which assigns the first two attributes to 
     246  the x and y axis and the class attribute to the color. At this phase, you 
     247  shouldn't call any functions that depend on the settings, such as drawing 
     248  the graph. 
     249* Call :obj:`self.openContext` (more about the arguments later). This will 
     250  search for a suitable context and assign the controls new values if one is 
     251  found. If there is no saved context that can be used, a new context is 
     252  created and filled with the default values that were assigned at the previous 
     253  point. 
     254* Finally, adjust the widget according to the retrieved controls. Scatter plot 
     255  now plots the graph by calling :obj:`updateGraph`. 
     256 
     257 
     258:obj:`closeContext` has an argument, the name of the context. If omitted 
     259(like above), the default name (:obj:`""`) is used. When opening the context, 
     260we give the name and some arguments on which the context depends. In case of 
     261:obj:`DomainContextHandler`, which scatter plot uses, we can give it a domain 
     262or any object that has a field :obj:`domain` containing a domain. Whether a 
     263saved context can be reused is judged upon the presence of attributes in the 
     264domain. 
     265 
     266If the widget is constructed appropriately (that is, if it strictly uses OWGUI 
     267controls instead of the Qt's), no other administration is needed to switch the 
     268context. 
     269 
     270Except for declaring the context settings, that is. Scatter plot has this just 
     271below the :obj:`settingsList`:: 
    251272 
    252273    contextHandlers = {"": DomainContextHandler("", 
     
    257278       ("attrSize", DomainContextHandler.Optional)])} 
    258279 
    259 :obj:`contextHandlers` is a dictionary whose keys are contexts' names. Each widget can have multiple contexts; for an unrealistic example, consider a scatter plot which gets two data sets and uses one attribute from the first for the x axis, and an attribute from the other for y. Since we won't see this often, the default name for a context is an empty string. 
    260  
    261 The values in the dictionary are context handlers. Scatter plot declares that it has a DomainContextHandler with name "" (sorry for the repetition) with attributes "attrX", "attrY", "attrLabel", "attrShape" and "attrSize". The first two are required, while the other three are optional. 
     280:obj:`contextHandlers` is a dictionary whose keys are contexts' names. Each 
     281widget can have multiple contexts; for an unrealistic example, consider a 
     282scatter plot which gets two data sets and uses one attribute from the first 
     283for the x axis, and an attribute from the other for y. Since we won't see this 
     284often, the default name for a context is an empty string. 
     285 
     286The values in the dictionary are context handlers. Scatter plot declares that 
     287it has a DomainContextHandler with name "" (sorry for the repetition) with 
     288attributes "attrX", "attrY", "attrLabel", "attrShape" and "attrSize". The 
     289first two are required, while the other three are optional. 
    262290 
    263291********************************* 
     
    265293********************************* 
    266294 
    267 What we said above is not exactly 
    268 true. :obj:`DomainContextHandler.Required` is the default flag, 
    269 so :obj:`("attrX", DomainContextHandler.Required)` can be 
    270 replaced by simply :obj:`"attrX"`. And the latter three have the 
     295What we said above is not exactly true. :obj:`DomainContextHandler.Required` 
     296is the default flag, so :obj:`("attrX", DomainContextHandler.Required)` can 
     297be replaced by simply :obj:`"attrX"`. And the latter three have the 
    271298same flags, so they can be grouped into :obj:`(["attrLabel", 
    272299"attrShape", "attrSize"], DomainContextHandler.Optional)`. So 
     
    277304       (["attrLabel", "attrShape", "attrSize"], DomainContextHandler.Optional)])} 
    278305 
    279 What do "optional" and "required" mean? Say that you used the 
     306What do ``Optional`` and ``Required`` mean? Say that you used the 
    280307scatter plot on the data with attributes A, B, C and D; A and B are 
    281308used for the x and y axis and D defined the colors of examples. Now 
     
    295322:obj:`DomainContextHandler`. 
    296323 
    297 DomainContextHandler's constructor has the following arguments 
    298  
    299 contextName 
    300 The name of the context; it should consist of letters and digits (it is used as a prt of a variable name). In case the widget has multiple contexts, they should have unique names. In most cases there will be only one context, so you can leave it empty. 
    301  
    302 fields 
    303 The names of the attributes to be saved and the corresponding flags. They are described in more details below. 
    304  
    305 cloneIfImperfect 
    306 states that when the context doesn't match perfectly, that is, unless the domain is exactly the same as the domain from which the context was originally created, :obj:`openContext` shouldn't reuse a context but create a copy of the best matching context instead. Default is :obj:`True`. 
    307  
    308 loadImperfect 
    309 tells whether the contexts that do not match perfectly (see above) should be used or not. Default is :obj:`True`. 
    310  
    311 findImperfect 
    312 tells whether imperfect contexts match at all or not (this flag is somewhat confused with :obj:`loadImperfect`, but it may come useful some day. Default is :obj:`True` again. 
    313  
    314 syncWithGlobal 
    315 tells whether instances of this widget should have a shared list of contexts (default). The alternative is that each keeps its own list; each individual list is merged with the global when the widget is deleted from the canvas (or when the canvas is closed). This setting only applies to canvas, while in saved applications widgets always have separate settings lists. 
    316  
    317 maxAttributesToPickle 
    318 To keep the size of the context file small, settings for domains exceeding a certain number of attributes are not pickled. Default is 100, but you can increase (or decrease this) if you need to. 
     324:class:`DomainContextHandler`'s constructor has the following arguments 
     325 
     326`contextName` 
     327   The name of the context; it should consist of letters and digits (it is 
     328   used as a part of a variable name). In case the widget has multiple 
     329   contexts, they should have unique names. In most cases there will be only 
     330   one context, so you can leave it empty. 
     331 
     332`fields` 
     333   The names of the attributes to be saved and the corresponding flags. They 
     334   are described in more details below. 
     335 
     336`cloneIfImperfect` 
     337   States that when the context doesn't match perfectly, that is, unless the 
     338   domain is exactly the same as the domain from which the context was 
     339   originally created, :obj:`openContext` shouldn't reuse a context but create 
     340   a copy of the best matching context instead. Default is :obj:`True`. 
     341 
     342`loadImperfect` 
     343   tells whether the contexts that do not match perfectly (see above) should 
     344   be used or not. Default is :obj:`True`. 
     345 
     346`findImperfect` 
     347   Tells whether imperfect contexts match at all or not (this flag is 
     348   somewhat confused with :obj:`loadImperfect`, but it may come useful some 
     349   day). Default is :obj:`True` again. 
     350 
     351`syncWithGlobal` 
     352   Tells whether instances of this widget should have a shared list of 
     353   contexts (default). The alternative is that each keeps its own list; 
     354   each individual list is merged with the global when the widget is deleted 
     355   from the canvas (or when the canvas is closed). This setting only applies 
     356   to canvas, while in saved applications widgets always have separate settings 
     357   lists. 
     358 
     359`maxAttributesToPickle` 
     360   To keep the size of the context file small, settings for domains exceeding 
     361   a certain number of attributes are not pickled. Default is 100, but you can 
     362   increase (or decrease this) if you need to. 
    319363 
    320364 
     
    326370name (just like in :obj:`settingsList`) and a flag. Here are the possible flags: 
    327371 
    328 * :obj:`DomainContextHandler.Optional`, :obj:`DomainContextHandler.SelectedRequired` and :obj:`DomainContextHandler.Required` state whether the attribute is optional or required, as explained above. Default is :obj:`Required`. :obj:`DomainContextHandler.SelectedRequired` is applicable only if the control is a list box, where it means that the attributes that are selected are required while the other attributes from the list are not. 
    329 * :obj:`DomainContextHandler.NotAttribute` the setting is not an attribute name. You can essentially make a check box context dependent, but we very strongly dissuade from this since it can really confuse the user if some check boxes change with the data while most do not. 
    330 * :obj:`DomainContextHandler.List` tells that the attribute corresponds to a list box. 
     372* :obj:`DomainContextHandler.Optional`, 
     373  :obj:`DomainContextHandler.SelectedRequired` and 
     374  :obj:`DomainContextHandler.Required` state whether the attribute is optional 
     375  or required, as explained above. Default is :obj:`Required`. 
     376  :obj:`DomainContextHandler.SelectedRequired` is applicable only if the 
     377  control is a list box, where it means that the attributes that are selected 
     378  are required while the other attributes from the list are not. 
     379 
     380* :obj:`DomainContextHandler.NotAttribute` the setting is not an attribute 
     381  name. You can essentially make a check box context dependent, but we very 
     382  strongly dissuade from this since it can really confuse the user if some 
     383  check boxes change with the data while most do not. 
     384 
     385* :obj:`DomainContextHandler.List` tells that the attribute corresponds to a 
     386  list box. 
    331387 
    332388 
     
    348404But the tuples are actually a shortcut for instances of 
    349405:obj:`ContextField`. When you say :obj:`"attrX"` this is actually 
    350 :obj:`ContextField("attrX", DomainContextHandler.Required)` (you should 
    351 appreciate the shortcurt, right?). But see this monster from widget "Select 
    352 Attributes" (file OWDataDomain.py):: 
    353  
    354     contextHandlers = {"": DomainContextHandler("", 
    355         [ContextField("chosenAttributes", 
    356                        DomainContextHandler.RequiredList, 
    357                        selected="selectedChosen", reservoir="inputAttributes"), 
    358          ContextField("classAttribute", 
    359                        DomainContextHandler.RequiredList, 
    360                        selected="selectedClass", reservoir="inputAttributes"), 
    361          ContextField("metaAttributes", 
    362                        DomainContextHandler.RequiredList, 
    363                        selected="selectedMeta", reservoir="inputAttributes") 
    364     ])} 
    365  
    366  
    367 :obj:`ContextField`'s constructor gets the name and flags and a list of 
    368 arguments that are written directly into the object instance. To follow the 
    369 example, recall what Select Attributes looks like: it allows you to select a 
    370 subset of attributes, the class attribute and the meta attributes that you 
    371 want to use; the attributes in the corresponding three list boxes are stored 
    372 in the widget's variables :obj:`chosenAttributes`, :obj:`classAttribute` 
    373 and :obj:`metaAttributes` respectively. When the user selects some attributes 
    374 in any of these boxes, the selection is stored in :obj:`selectedChosen`, 
    375 :obj:`selectedClass` and :obj:`selectedMeta`. The remaining attributes 
    376 - those that are not in any of these three list boxes - are in the leftover 
    377 listbox on the left-hand side of the widget, and the content of the box is 
    378 stored in the widget's variable :obj:`inputAttributes`. 
    379  
    380 The above definition tells that the context needs to store the contents of 
    381 the three list boxes by specifying the corresponding variables; the list of 
    382 attributes is given as the name of the field and the list of selected 
    383 attributes is in the optional named attribute :obj:`selected`. By 
    384 :obj:`reservoir` we told the context handler that the attributes are taken 
    385 from :obj:`inputAttributes`. So, when a context is retrieved, all the 
    386 attributes that are not in any of the three list boxes are put into 
    387 :obj:`inputAttributes`. 
    388  
    389 Why the mess? Couldn't we just store :obj:`inputAttributes` as the fourth 
    390 list box? Imagine that the user first loads the data with attributes A, B, 
    391 C, D, E and F, puts A, B, C in chosen and D in class. E and F are left in 
    392 :obj:`inputAttributes`. Now she loads another data which has attributes A, 
    393 B, C, D, E, and G. The contexts should match (the new data has all the 
    394 attributes we need), but :obj:`inputAttributes` should now contain E and 
    395 G, not E and F, since F doesn't exist any more, while G needs to be made 
    396 available. 
    397  
    398 You can use :obj:`ContextField` (instead of tuples and strings) for 
    399 declaring any fields, but you will usually need them only for lists or, 
    400 maybe, some complicated future controls. 
     406:obj:`ContextField("attrX", DomainContextHandler.Required)` 
     407 
     408.. 
     409   But see this monster from widget "Select Attributes" (file OWDataDomain.py):: 
     410 
     411       contextHandlers = {"": DomainContextHandler("", 
     412           [ContextField("chosenAttributes", 
     413                          DomainContextHandler.RequiredList, 
     414                          selected="selectedChosen", reservoir="inputAttributes"), 
     415            ContextField("classAttribute", 
     416                          DomainContextHandler.RequiredList, 
     417                          selected="selectedClass", reservoir="inputAttributes"), 
     418            ContextField("metaAttributes", 
     419                          DomainContextHandler.RequiredList, 
     420                          selected="selectedMeta", reservoir="inputAttributes") 
     421       ])} 
     422 
     423 
     424   :obj:`ContextField`'s constructor gets the name and flags and a list of 
     425   arguments that are written directly into the object instance. To follow the 
     426   example, recall what Select Attributes looks like: it allows you to select a 
     427   subset of attributes, the class attribute and the meta attributes that you 
     428   want to use; the attributes in the corresponding three list boxes are stored 
     429   in the widget's variables :obj:`chosenAttributes`, :obj:`classAttribute` 
     430   and :obj:`metaAttributes` respectively. When the user selects some attributes 
     431   in any of these boxes, the selection is stored in :obj:`selectedChosen`, 
     432   :obj:`selectedClass` and :obj:`selectedMeta`. The remaining attributes 
     433   - those that are not in any of these three list boxes - are in the leftover 
     434   listbox on the left-hand side of the widget, and the content of the box is 
     435   stored in the widget's variable :obj:`inputAttributes`. 
     436 
     437   The above definition tells that the context needs to store the contents of 
     438   the three list boxes by specifying the corresponding variables; the list of 
     439   attributes is given as the name of the field and the list of selected 
     440   attributes is in the optional named attribute :obj:`selected`. By 
     441   :obj:`reservoir` we told the context handler that the attributes are taken 
     442   from :obj:`inputAttributes`. So, when a context is retrieved, all the 
     443   attributes that are not in any of the three list boxes are put into 
     444   :obj:`inputAttributes`. 
     445 
     446   Why the mess? Couldn't we just store :obj:`inputAttributes` as the fourth 
     447   list box? Imagine that the user first loads the data with attributes A, B, 
     448   C, D, E and F, puts A, B, C in chosen and D in class. E and F are left in 
     449   :obj:`inputAttributes`. Now she loads another data which has attributes A, 
     450   B, C, D, E, and G. The contexts should match (the new data has all the 
     451   attributes we need), but :obj:`inputAttributes` should now contain E and 
     452   G, not E and F, since F doesn't exist any more, while G needs to be made 
     453   available. 
     454 
     455   You can use :obj:`ContextField` (instead of tuples and strings) for 
     456   declaring any fields, but you will usually need them only for lists or, 
     457   maybe, some complicated future controls. 
    401458 
    402459 
     
    405462***************************** 
    406463 
    407 Avoid it if you can. If you can't, here's the list of the methods you may need to implement. You may want to copy as much from the :obj:`DomainContextHandler` as you can. 
    408  
    409  
    410 __init__ 
    411 Has the same arguments as the :obj:`DomainContextHandler`'s, except for the :obj:`fields`. 
    412  
    413 newContext 
    414 Creates and returns a new context. In :obj:`ContextHandler` is returns an instance of :obj:`Context`; you probably won't need to change this. 
    415  
    416 openContext 
    417 The method is given a widget and some additional arguments based on which the contexts are compared. In case of :obj:`DomainContextHandler` this is a domain. There can be one or more such arguments. Note that the method :obj:`openContext` which we talked about above is a method of :obj:`OWBaseWidget`, while here we describe a method of context handlers. Actually, :obj:`OWBaseWidget(self, contextName, *args)` calls the context handler's, passing it's :obj:`self` and :obj:`*args`. 
    418  
    419 It needs to find a matching context and copy its settings to the widget or construct a new context and copy the settings from the widget. Also, when an old context is reused, it should be moved to the beginning of the list. :obj:`ContextHandler` already defines this method, which should usually suffice. :obj:`DomainContextHandler` adds very little to it. 
    420  
    421 closeContext 
    422 Copies the settings from the widget by calling :obj:`settingsFromWidget`. You probably won't need to overwrite it. 
    423  
    424 match 
    425 The method is called by :obj:`openContext` to find a matching context. Given an existing context and the arguments that were given to :obj:`openContext` (for instance, a domain), it should decide whether the context matches or not. If it returns 2, it is a perfect match (e.g. domains are the same). If it returns 0, the context is not applicable (e.g. some of the required attributes are missing). In case it returns a number between 0 and 1 (excluding 0), the higher the number the better the match. :obj:`openContext` will use the best matching context (or the perfect one, if found). 
    426  
    427 settingsToWidget/settingsFromWidget 
    428 Copy the settings to and from the widget. 
    429  
    430 fastSave 
    431 This function is called by the widget's :obj:`__setattr__` each time any widget's variable is changed to immediately synchronize the context with the state of the widget. The method is really needed only when :obj:`syncWithGlobal` is set. When the context is closed, :obj:`closeContext` will save the settings anyway. 
    432  
    433 cloneContext 
    434 Given an existing context, it prepares and returns a copy. The method is optional; :obj:`copy.deepcopy` can be used instead. 
     464Avoid it if you can. If you can't, here's the list of the methods you may need 
     465to implement. You may want to copy as much from the :obj:`DomainContextHandler` 
     466as you can. 
     467 
     468 
     469:obj:`__init__` 
     470   Has the same arguments as the :obj:`DomainContextHandler`'s, except for the 
     471   :obj:`fields`. 
     472 
     473:obj:`newContext()` 
     474   Creates and returns a new context. In :obj:`ContextHandler` it returns an 
     475   instance of :obj:`Context`; you probably won't need to change this. 
     476 
     477:obj:`openContext(widget, *args)` 
     478   The method is given a widget and some additional arguments based on which 
     479   the contexts are compared. In case of :obj:`DomainContextHandler` this is 
     480   a domain. There can be one or more such arguments. Note that the method 
     481   :obj:`openContext` which we talked about above is a method of 
     482   :obj:`OWBaseWidget`, while here we describe a method of context handlers. 
     483   Actually, :obj:`OWBaseWidget.openContext(self,contextName, *args)` calls 
     484   the context handler's, passing it's :obj:`self` and :obj:`*args`. 
     485 
     486   It needs to find a matching context and copy its settings to the widget or 
     487   construct a new context and copy the settings from the widget. Also, when an 
     488   old context is reused, it should be moved to the beginning of the list. 
     489   :obj:`ContextHandler` already defines this method, which should usually 
     490   suffice. :obj:`DomainContextHandler` adds very little to it. 
     491 
     492:obj:`closeContext` 
     493   Copies the settings from the widget by calling :obj:`settingsFromWidget`. 
     494   You probably won't need to overwrite it. 
     495 
     496:obj:`match` 
     497   The method is called by :obj:`openContext` to find a matching context. 
     498   Given an existing context and the arguments that were given to 
     499   :obj:`openContext` (for instance, a domain), it should decide whether the 
     500   context matches or not. If it returns 2, it is a perfect match (e.g. 
     501   domains are the same). If it returns 0, the context is not applicable 
     502   (e.g. some of the required attributes are missing). In case it returns a 
     503   number between 0 and 1 (excluding 0), the higher the number the better the 
     504   match. :obj:`openContext` will use the best matching context (or the 
     505   perfect one, if found). 
     506 
     507:obj:`settingsToWidget` / :obj:`settingsFromWidget` 
     508   Copy the settings to and from the widget. 
     509 
     510:obj:`fastSave` 
     511   This function is called by the widget's :obj:`__setattr__` each time any 
     512   widget's variable is changed to immediately synchronize the context with 
     513   the state of the widget. The method is really needed only when 
     514   :obj:`syncWithGlobal` is set. When the context is closed, 
     515   :obj:`closeContext` will save the settings anyway. 
     516 
     517:obj:`cloneContext` 
     518   Given an existing context, it prepares and returns a copy. The method is 
     519   optional; :obj:`copy.deepcopy` can be used instead. 
    435520 
    436521 
     
    440525 
    441526Settings can be saved in two different places. Orange Canvas save 
    442 settings in .ini files in directory 
    443 Orange/OrangeWidgets/widgetSettings. Each widget type has its separate 
    444 file; for instance, the scatter plot's settings are saved in 
     527settings in .ini files in its application data directory. Each widget type has 
     528a separate file; for instance, the scatter plot's settings are saved in 
    445529:obj:`ScatterPlot.ini`. Saved schemas and applications save 
    446530settings in .sav files; the .sav file is placed in the same directory 
     
    451535Saving and loading is done automatically by canvas or the 
    452536application. In a very rare case you need it to run these operations 
    453 manually, the functions involved are :obj:`loadSettings(self, file = 
    454 None)`, :obj:`saveSettings(self, file = None)`, 
    455 :obj:`loadSettingsStr(self, str)`, 
     537manually, the functions involved are :obj:`loadSettings(self, file=None)`, 
     538:obj:`saveSettings(self, file=None)`, :obj:`loadSettingsStr(self, str)`, 
    456539:obj:`saveSettingsStr(self)`. The first two load and save from 
    457540the file; if not given, the default name (widget's name + 
Note: See TracChangeset for help on using the changeset viewer.