source: orange/docs/extend-widgets/rst/owgui.rst @ 11439:2a63a9963207

Revision 11439:2a63a9963207, 16.1 KB checked in by Ales Erjavec <ales.erjavec@…>, 13 months ago (diff)

Small fixes to widget development documentation.

Line 
1.. module:: OWGUI
2
3#####################################
4OWGUI: Library of Common GUI Controls
5#####################################
6
7Orange Widgets wrap Orange's classes in an easy to use interactive graphical
8interface. As such, much of their code is about the interface, event control
9and maintaining the state of the GUI controls.
10
11In the spirit of constructive laziness, we wrote a library using which a single
12line of code can construct a check box, line edit or a combo, make it being
13synchronized with a Python object's attribute (which, by the way, gets
14automatically saved and retrieved when the widgets is closed and reopened),
15attaches a callback function to the control, make it disable or enable other
16controls...
17
18*****************
19Common Attributes
20*****************
21
22Many functions that construct controls share one or more common arguments,
23usually in the same order. These are described here. Descriptions of individual
24controls will only list their specific arguments, while the arguments which are
25presented here will only be described in cases where they have a different meaning.
26
27`widget` (required)
28   Widget on which control will be drawn - can be widget's :obj:`controlArea`
29   or another box.
30
31`master` (required)
32   Object which includes an attribute that are used to store control's
33   state, most often the object which called the function that
34   initialized the control.
35
36`value` (required)
37   String with the name of the master's attribute that synchronizes with the
38   state of the control (and vice-versa - when this attribute is changed, the
39   control changes as well). This attribute should usually be also included
40   the master's :obj:`settingsList`, so that it is automatically saved and
41   retrieved.
42
43`box` (default: None)
44   Indicates if there should be a box that is drawn around the control.
45   If `box` is ``None``, no box is drawn; if it is a string, it is also used
46   as box's name. If `box` is any other true value (such as ``True`` :),
47   an unlabeled box is drawn.
48
49`callback` (default: None)
50   A function to be called when the state of the control is changed. Can
51   include a single function, or a list of functions that will be called in
52   the order provided. If callback function changes the value of the controlled
53   attribute (the one given as the `value` argument described above) it may
54   trigger a cycle
55
56   ..
57      ; a simple trick to avoid this is shown in the description
58      of :func:`listBox` function.
59
60`tooltip` (default: None)
61   A string that is displayed in a tooltip that appears when mouse is over the
62   control.
63
64`label` (default: None)
65   A string that is displayed as control's label.
66
67`labelWidth` (default: None)
68   Sets the label's width. This is useful for aligning the controls.
69
70`orientation` (default: "vertical")
71   When label is used, determines the relative placement of the label and the
72   control. Label can be above the control, "vertical", or in the same line
73   with control, "horizontal". Instead of "vertical" and "horizontal" you can
74   also use ``True`` and ``False`` or 1 and 0, respectively. (Remember this
75   as "vertical" being the usual order of controls in the widgets, so vertical
76   is "true".)
77
78`disabled` (default: False)
79   Tells whether the control be disabled upon the initialization.
80
81`addSpace` (default: False)
82   If true, a space of 8 pixels is added after the widget by calling
83   :func:`separator`. `addSpace` can also be an integer specifying the height
84   of the added space.
85
86
87********
88Controls
89********
90
91This section describes the OWGUI wrappers for controls like check boxes, buttons
92and similar. All the important Qt's controls can be constructed through this
93functions.
94
95..
96   You should always use them instead of calling Qt directly, not only
97   because they are convenient, but also because they set up a lot of things
98   that happen in behind.
99
100
101Check Box
102*********
103
104Check box, a wrapper around QCheckBox, adding a label, box, tooltip, callback
105and synchronization with the designated widget's attribute.
106
107.. function:: checkBox(widget, master, value, label[, box, tooltip, callback, disabled, labelWidth, disables])
108
109   `disables` (default: [])
110      If the check box needs to disable some other controls they can be given
111      in list  `disables`, e.g. ``disables=[someOtherCheckBox, someLineEdit]``.
112      If the other control should be disabled when the checkbox is checked, do
113      it like this: ``disables=[someOtherCheckBox, (-1, someLineEdit)]`` - now
114      `someOtherCheckBox` will be enabled when this check box is checked,
115      while `someLineEdit` will be enabled when the check box is unchecked.
116
117   `labelWidth` (default: None)
118      `labelWidth` can be used to align this widget with others.
119
120
121Line Edit
122*********
123
124Edit box, a wrapper around QLineEdit.
125
126.. function:: lineEdit(widget, master, value[, label, labelWidth, orientation, box, tooltip, callback, valueType, validator, controlWidth])
127
128   `valueType` (default: str)
129      A type into which the `value` is cast.
130
131   `validator` (default: None)
132      A standard Qt validator that can be associated with the control.
133
134
135Button
136******
137
138A wrapper around QPushButton, just to be able to define a button
139and its callback in a single line.
140
141.. function:: button(widget, master, label[, callback, disabled, tooltip])
142
143
144Radio Buttons
145*************
146
147OWGUI can create an individual radio button or a box of radio buttons or an
148individual radio button.
149
150An individual radio button is created by :obj:`radioButton`.
151
152.. function:: radioButton(widget, master, value, label[, box, tooltip, callback, addSpace])
153
154   The function provides the usual capabilities of OWGUI controls. It is though
155   your responsibility to put it in something like a :obj:`QVButtonGroup`.
156
157A box of radio buttons is created by function :obj:`radioButtonsInBox`.
158
159.. function:: radioButtonsInBox(widget, master, value, btnLabels[, box, tooltips, callback)
160
161   `value` (required)
162      Synchronized with the index of the selected radio button.
163
164   `btnLabels` (required)
165      A list with labels for radio buttons. Labels can be strings or pixmaps.
166
167   `tooltips` (default: None)
168      A list of tooltips, one for each button.
169
170
171Combo Box
172*********
173
174A wrapper around QComboBox.
175
176.. function:: comboBox(widget, master, value[, box, label, labelWidth, orientation, items, tooltip, callback, sendSelectedValue, valueType, control2attributeDict, emptyString])
177
178   `items` (default: [])
179      A list of combo box's items. Unlike most OWGUI, `items` have one
180      Orange-specific quirk: its element can be either a string, in which
181      case it is used as a label, or a tuple, where the first element is a
182      label name and the last is the attribute type which is used to create
183      an icon. Most attribute lists in Orange Widgets are constructed this way.
184
185   `sendSelectedValue` (default: 0)
186      If false, attribute `value` will be assigned the index of the selected
187      item. Otherwise, it is assigned the currently selected item's label.
188
189   `control2attributeDict` (default: {})
190      A dictionary for translating the item's label into `value`. It is used
191      only is `sendSelectedValue` is true, and even then a label is translated
192      only if an item with such a key is found in the dictionary; otherwise,
193      label is written to `value` as it is.
194
195   `emptyString` (default: "")
196      Tells which combo box's item corresponds to an empty `value`. This is
197      typically used when combo box's labels are attribute names and an item
198      "(none)", which allows user to select no attribute. If we give
199      ``emptyString="(none)"``, `value` will be an empty string when the user
200      selects "(none)". This is equivalent to specifying
201      ``control2attributeDict={"(none)": ""}`` (and is actually implemented
202      like that), but far more convenient.
203
204   `valueType` (default: str or unicode)
205      A function through which the currently selected item's label is
206      converted prior to looking into `control2attributeDict`. Needed to
207      convert Qt's QString.
208
209
210List Box
211********
212
213This control, which might be the most complicated control in OWGUI, is a
214sophisticated wrapper around QListBox. It's complexity arises from
215synchronization.
216
217
218.. function:: listBox(widget, master, value, labels[, box, tooltip, callback, selectionMode])
219
220   `value` (required)
221      The name of master's attribute containing indices of all selected values.
222
223   `labels` (required)
224      The name of master's attribute containing the list box's labels. Similar
225      to `items` in combo box, list `labels` have one Orange-specific quirk:
226      its element can be either a string, in which case it is used as a label
227      or a tuple, where the first element is a label name and the second can
228      be either an icon on an integer, representing the attribute type which
229      is used to create an icon. Most attribute lists in Orange Widgets are
230      constructed this way.
231
232   `selectionMode` (default: QListWidget.SingleSelection)
233      Tells whether the user can select a single item
234      (:obj:`QListWidget.SingleSelection`), multiple items
235      (:obj:`QListWidget.MultiSelection`, :obj:`QListWidget.ExtendedSelection`)
236      or nothing (:obj:`QListWidget.NoSelection`).
237
238   `value` is automatically cast to :obj:`OWGUI.ControlledList` (this is
239   needed because the list should report any changes to the control, the list
240   box; :obj:`OWGUI.ControlledList` is like an ordinary Python :obj:`list`
241   except that it triggers synchronization with the list box at every change).
242
243   `labels` is only partially synchronized with the list box: if a new list
244   is assigning to `labels` attribute, the list will change. If elements of
245   the existing list are changed or added, the list box won't budge. You
246   should never change the list, but always assign a new list (or reassign
247   the same after it's changed). If the labels are stored in
248   ``self.listLabels`` and you write ``self.listLabels[1]="a new label"``,
249   the list box won't change. To trigger the synchronization, you should
250   continue by ``self.listLabels = self.listLabels``. This may seem awkward,
251   but by our experience a list of selected items is seldom changed changed
252   "per-item", so we were too lazy to write the annoyingly complex backward
253   callbacks.
254
255
256Spin
257****
258
259Spin control, a wrapper around QSpinBox.
260
261.. function:: spin(widget, master, value, min, max[, step, box, label, labelWidth, orientation, tooltip, callback, controlWidth])
262
263   `min`, `max`, `step=1`
264      Minimal and maximal value, and step.
265
266
267Slider
268******
269
270A wrapper around QSlider that allows user setting a numerical value between
271the given bounds.
272
273.. function:: hSlider(widget, master, value[, box, minValue, maxValue, step, callback, labelFormat, ticks, divideFactor])
274
275
276   `minValue` (default: 0), `maxValue` (default: 10), `step` (default: 1)
277      Minimal and maximal value for the spin control, and its step.
278
279   `ticks` (default: 0)
280      If non-zero, it gives the interval between two ticks. The ticks will
281      appear below the groove.
282
283   `labelFormat` (default: " %d")
284      Defines the look of the label on the righthand side of the slider. It
285      has to contain one format character (like %d in the default), but can
286      contain other text as well.
287
288   `divideFactor` (default: 1.0)
289      The value printed in the label is divided by `divideFactor`.
290
291
292Check Box with Spin
293*******************
294
295Check box with spin, or, essentially, a wrapper around OWGUI.checkBox and
296OWGUI.spin.
297
298.. function:: checkWithSpin(widget, master, label, min, max, checked, value[, posttext, step, tooltip, checkCallback, spinCallback, labelWidth])
299
300   `min`, `max`, `step` (required)
301      Minimal and maximal value for the spin control, and its step.
302
303   `checked` (required)
304      Master's attribute that is synchronized with the state of the check box.
305
306   `value` (required)
307      The attribute that is synchronized with the spin.
308
309   `posttext` (default: None)
310      Text which appears on the right-hand side of the control.
311
312   `checkCallback` (default: None), `spinCallback` (default: None)
313      Function that are called when the state of the check box or spin changes.
314
315
316Labels
317******
318
319There are two functions for constructing labels. The first is a simple wrapper
320around QLabel which differs only in allowing to specify a fixed width without
321needing an extra line. Note that unlike most other OWGUI widgets, this one
322does not have the argument `master`.
323
324.. function:: widgetLabel(widget, label[, labelWidth])
325
326   The second is a label which can synchronize with values of master widget's
327   attributes.
328
329.. function:: label(widget, master, label[, labelWidth])
330
331   `label`
332      `label` is a format string following Python's syntax (see the
333      corresponding Python documentation): the label's content is rendered as
334      ``label % master.__dict__``.
335
336
337*********
338Utilities
339*********
340
341Widget box
342**********
343
344
345.. function:: widgetBox(widget, box=None, orientation='vertical', addSpace=False)
346
347   Creates a box in which other widgets can be put. If `box` is given
348   and not false, the box will be framed. If `box` is a string, it will
349   be used for the box name (don't capitalize each word; spaces in front or
350   after the string will be trimmed and replaced with a single space).
351   Argument `orientation` can be ``"vertical"`` or ``"horizontal"``
352   (or ``True`` and ``False``, or ``1`` and ``0``, respectively).
353
354
355Idented box
356***********
357
358
359.. function:: indentedBox(widget, sep=20)
360
361      Creates an indented box. Widgets which are subsequently put into
362      that box will be arranged vertically and aligned with an indentation
363      of `sep`.
364
365
366Inserting Space between Widgets
367*******************************
368
369Most widgets look better if we insert some vertical space between the controls
370or groups of controls. A few functions have an optional argument `addSpace`
371by which we can request such space to be added. For other occasions, we can use
372the following two functions.
373
374.. function:: separator(widget, width=0, height=8)
375
376   Function `separator` inserts a fixed amount of space into `widget`.
377   Although the caller can specify the amount, leaving the default will help the
378   widgets having uniform look.
379
380.. function:: rubber(widget[, orientation="vertical"])
381
382   Similar to separator, except that the size is (1, 1) and that it expands in the
383   specified direction if the widget is expanded. Most widgets should have rubber
384   somewhere in their :obj:`controlArea`.
385
386Attribute Icons
387***************
388
389.. function:: getAttributeIcons()
390
391   Returns a dictionary with attribute types (:obj:`orange.VarTypes.Discrete`,
392   :obj:`orange.VarTypes.Continuous`, :obj:`orange.VarTypes.String`, -1) as keys
393   and colored pixmaps as values. The dictionary can be used in list and combo
394   boxes showing attributes for easier distinguishing between attributes of different types.
395
396Send automatically / Send
397*************************
398
399Many widgets have a "Send" button (perhaps named "Apply", "Commit"...)
400accompanied with a check box "Send automatically", having the same effect as
401if the user pressed the button after each change. A well behaved widget cares
402to:
403
404* disable the button, when the check box is checked;
405* when the user checks the check box, the data needs to be send (or the
406  changes applied), but only if there is any pending change which has not been
407  (manually) sent yet.
408
409Programming this into every widget is annoying and error-prone; at the time
410when the function described here was written, not many widgets actually did
411this properly.
412
413.. function:: setStopper(master, sendButton, stopCheckbox, changedFlag, callback)
414
415   `sendButton`
416      The button that will be disabled when the check box is checked.
417
418   `stopCheckbox`
419      Check box that decides whether the changes are sent/commited/applied
420      automatically.
421
422   `changedFlag`
423      The name of the `master`'s attribute which tells whether there is a
424      change which has not been sent/applied yet.
425
426   `callback`
427      The function that sends the data or applies the changes. This is
428      typically the function which is also used as the `sendButton`'s callback.
429
430
431:obj:`setStopper` is a trivial three lines long function which connects a few
432signals. Its true importance is in enforcing the correct procedure for
433implementing such button-check box combinations.
434
435..
436   Make sure to carefully observe and follow the example provided below.
437
438   Missing, where did it go?
Note: See TracBrowser for help on using the repository browser.