source: orange/Orange/doc/extend-widgets/api.htm @ 10997:e82a939c44ce

Revision 10997:e82a939c44ce, 5.4 KB checked in by Ales Erjavec <ales.erjavec@…>, 18 months ago (diff)

Updated channel specification flags documentation in 'extend-widgets'.

Line 
1<html>
2<head>
3<title>Orange Widgets Reference Guide for Developers</title>
4<link rel=stylesheet HREF="../style.css" type="text/css">
5<link rel=stylesheet href="style-print.css" type="text/css" media=print>
6</head>
7<body>
8<h1>Orange Widgets Reference Guide for Developers</h1>
9
10<h2>Channels Definitions, Data Exchange</h2>
11
12<p>Input and output channels are defined anywhere within the
13<code>__init__</code> function of a main widget class. The definition
14is used when running a widget, but also when registering your widget
15within Orange Canvas. Channel definitions are optional, depending on
16what your widget does.
17
18<h3>Output Channels</h3>
19
20Following is an example that defines two output channels:</p>
21
22<xmp class="code">self.outputs = [("Sampled Data", orange.ExampleTable), ("Learner", orange.Learner)]
23</xmp>
24
25<p><code>self.outputs</code> should thus be a list of tuples, within
26each the first element is a name of the channel, and the second the
27type of the tokens that will be passed through. Token types are class
28names; most often these are some Orange classes, but they can also be
29anything you may define as class in Python.</p>
30
31<p>Widgets send the data by using <code>self.send</code> call,
32like:</p>
33
34<xmp class="code">self.send("Sampled Data", mydata)
35</xmp>
36
37<p>Parameters of <code>send</code> are channel name and a token to be
38send (e.g., a variable that holds the data to be send through the
39channel).</p>
40
41<p>When tokens are send around, the signaling mechanism annotates
42them with a pointer to an object that sent the toke (<em>e.g.</em>, a widget
43id). Additionally, this annotation can be coupled with some name
44passed to <code>send</code>, in case you have a widget that can send
45few tokens one after the other and you would like to enable a receiving widget
46recognize these are different tokens (and not updates of the same
47one):</p>
48
49<xmp class="code">id = 10
50self.send("Sampled Data", mydata, id)
51</xmp>
52
53<h3>Input Channels</h3>
54
55<p>An example of the simplest definition of an input channel is:</p>
56
57<xmp class="code">self.inputs = [("Data", orange.ExampleTable, self.receiveData)]
58</xmp>
59
60<p>Again, <code>self.inputs</code> is a list of tuples, where the
61elements are the name of the channel, followed by a channel type and a
62Python function that will be called with any token received. For the
63channel defined above, a corresponding receiving function would be of
64the type (we would most often define it within the widget class
65defintion, hence <code>self</code> for the first attribute):</p>
66
67<xmp class="code">def receiveData(self, data):
68   # handle data in some way
69</xmp>
70
71<p>Any time our widget would receive a token, <code>receiveData</code>
72would be called. Notice there would be no way of knowing anything
73about the sender of the token, hence widget would most often replace
74the previously received token with the new one, and forget about the
75old one.</p>
76
77<p>Widgets can often clear their output by sending a <code>None</code>
78as a token. Also, upon deletion of some widget, this is the way that
79Orange Canvas would inform all directly connected downstream widgets
80about deletion. Similar, when channels connecting two widgets are
81deleted, Orange Canvas would automatically send <code>None</code> to
82the receiving widget. Make sure your widget handles <code>None</code>
83tokens appropriately!</code>
84
85<p>There are cases when widget would like to know about the origin of
86a token. Say, you would like to input several learners to the
87evaluation widget, how would this distinguish between the learners of
88different origins? Remember (from above) that tokens are actually
89passed around with IDs (pointers to widgets that sent them). To
90declare a widget is interested about these IDs, one needs to define an
91input channel in the following way:</p>
92
93<xmp class="code">self.inputs = [("Learners", orange.Learner, self.learner, Multiple)]
94</xmp>
95
96<p>where the last argument refers if we have a "Single" (default if not
97specified) or a "Multiple" channel. For the above declared channel, the
98receiving function should include an extra argument for the ID, like:</p>
99
100<xmp class="code">def learner(self, learnertoken, tokenid):
101   # handle learnertoken and tokeid in some way
102</xmp>
103
104<p>Widgets such as <code>OWTestLearners</code> and alike use such
105schema.</p>
106
107<p>Finally, we may have input channels of the same type. If a widget
108would declare input channels like:</p>
109
110<xmp class="code">self.inputs = [("Data", orange.ExampleTable, self.maindata),
111               ("Additional Data", orange.ExampleTable, self.otherdata)]
112</xmp>
113
114<p>and we connect this widget in Orange Canvas to a sending widget
115that has a single orange.ExampleTable output channel, Canvas would
116bring up Set Channels dialog. There, a sending widget's channel could
117be connected to both receiving channels. As we would often prefer to
118connect to a single (default) channel instead (still allowing user of
119Orange Canvas to set up a different schema manually), we set that channel
120as the default. We do this by the using the fourth element in the channel
121definition list, like:</p>
122
123<xmp class="code">self.inputs = [("Data", orange.ExampleTable, self.maindata, Default),
124               ("Additional Data", orange.ExampleTable, self.otherdata)]
125</xmp>
126
127<hr>
128
129<p>Note: This documentation is not complete, we are now providing it as
130is, and are working on it to update it. Until then, you should find
131most information about widget APIs in the <a href="/doc/widgets">Tutorial</a>.
132
133</body>
134</html> 
Note: See TracBrowser for help on using the repository browser.