75
Orange Development Documentation Release 3 Orange Data Mining Jun 20, 2020

Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development DocumentationRelease 3

Orange Data Mining

Jun 20, 2020

Page 2: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer
Page 3: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Contents

1 Getting Started 11.1 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Defining a widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2 Getting Started (Continued) 72.1 A ‘Demo’ package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3 Tutorial (Settings and Controls) 133.1 Widgets Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.2 Controls and module gui . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.3 Persisting defaults . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163.4 Context dependent settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173.5 Migrations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

4 Channels and Tokens 214.1 Multi-Input Channels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214.2 Using Several Output Channels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244.3 Default Channels (When Using Input Channels of the Same Type) . . . . . . . . . . . . . . . . . . . 254.4 Explicit Channels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

5 Responsive GUI 275.1 Setting up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275.2 Starting a task in a thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285.3 Collecting results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305.4 Stopping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

6 Utilities 336.1 Progress Bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336.2 Issuing warning and errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346.3 I/O Summaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356.4 Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

7 OWWidget 397.1 Widget Meta Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397.2 Input/Output Signal Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407.3 Sending/Receiving . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427.4 Accessing Controls though Attribute Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

i

Page 4: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

7.5 Class Member Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

8 Library of Common GUI Controls 458.1 Common options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458.2 Common Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468.3 Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468.4 Common Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468.5 Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468.6 Other widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528.7 Utility functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538.8 Internal functions and classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

9 Debugging and testing 579.1 Running widgets as scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579.2 Unit-testing Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

10 API 6110.1 Orange.widgets.utils.concurrent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

Python Module Index 67

Index 69

ii

Page 5: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

CHAPTER 1

Getting Started

Orange Widgets are components in Orange Canvas, a visual programming environment of Orange. They representsome self contained functionalities and provide a graphical user interface (GUI). Widgets communicate with eachother and pass objects through communication channels to interact with other widgets.

On this page, we will start with some simple essentials, and then show you how to build a simple widget that will beready to run within Orange Canvas.

1.1 Prerequisites

Each Orange widget belongs to a category and has an associated priority within that category. When opening OrangeCanvas, a visual programming environment that comes with Orange, widgets are listed in a toolbox on the left:

1

Page 6: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

Each widget has a name description and a set of input/outputs (referred to as the widget’s meta description).

This meta data is discovered at Orange Canvas application startup leveraging setuptools/distribute and its entry pointsprotocol. Orange Canvas looks for widgets using an orange.widgets entry point.

1.2 Defining a widget

OWWidget is the base class of a widget in the Orange Canvas workflow.

Every widget in the canvas framework needs to define its meta data. This includes the widget’s name and text de-scriptions and more importantly its input/output specification. This is done by defining constants in the widget’s classnamespace.

2 Chapter 1. Getting Started

Page 7: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

We will start with a very simple example. A widget that will output a single integer specified by the user.

from Orange.widgets.widget import OWWidget, Outputfrom Orange.widgets.settings import Settingfrom Orange.widgets import gui

class IntNumber(OWWidget):# Widget's name as displayed in the canvasname = "Integer Number"# Short widget descriptiondescription = "Lets the user input a number"

# An icon resource file path for this widget# (a path relative to the module where this widget is defined)icon = "icons/number.svg"

# Widget's outputs; here, a single output named "Number", of type intclass Outputs:

number = Output("Number", int)

By design principle, Orange widgets in an interface are most often split to control and main area. Control area appearson the left and should include any controls for settings or options that your widget will use. Main area would mostoften include a graph, table or some drawing that will be based on the inputs to the widget and current options/settingin the control area. OWWidget makes these two areas available through its attributes self.controlArea andself.mainArea. Notice that while it would be nice for all widgets to have this common visual look, you can usethese areas in any way you want, even disregarding one and composing your widget completely unlike the others inOrange.

We specify the default layout with class attribute flags. Here we will only be using a single column (controlArea) GUI.

# Basic (convenience) GUI definition:# a simple 'single column' GUI layoutwant_main_area = False# with a fixed non resizable geometry.resizing_enabled = False

We want the current number entered by the user to be saved and restored when saving/loading a workflow. We canachieve this by declaring a special property/member in the widget’s class definition like so:

number = Setting(42)

And finally the actual code to define the GUI and the associated widget functionality:

def __init__(self):super().__init__()

from AnyQt.QtGui import QIntValidatorgui.lineEdit(self.controlArea, self, "number", "Enter a number",

box="Number",callback=self.number_changed,valueType=int, validator=QIntValidator())

self.number_changed()

def number_changed(self):# Send the entered number on "Number" outputself.Outputs.number.send(self.number)

See also:

1.2. Defining a widget 3

Page 8: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

Orange.widgets.gui.lineEdit(),

By itself this widget is useless because no widget accepts its output. So let us define a widget that displays a number.

from Orange.widgets.widget import OWWidget, Inputfrom Orange.widgets import gui

class Print(OWWidget):name = "Print"description = "Print out a number"icon = "icons/print.svg"

class Inputs:number = Input("Number", int)

want_main_area = False

def __init__(self):super().__init__()self.number = None

self.label = gui.widgetLabel(self.controlArea, "The number is: ??")

@Inputs.numberdef set_number(self, number):

"""Set the input number."""self.number = numberif self.number is None:

self.label.setText("The number is: ??")else:

self.label.setText("The number is {}".format(self.number))

We define inputs with a class Inputs, just like outputs are defined by Outputs. However, each input must be handledby a class methods. We mark the handlers by decorating them; in above case by putting @Inputs.number before themethod’s definition.

Notice how in the set_number method we check whether the number is None. None is sent to the widget when aconnection between the widgets is removed or if the sending widget to which we are connected intentionally emptiedthe channel.

Now we can use one widget to input a number and another to display it.

One more:

from Orange.widgets.widget import OWWidget, Input, Output

class Adder(OWWidget):name = "Add two integers"description = "Add two numbers"icon = "icons/add.svg"

class Inputs:a = Input("A", int)b = Input("B", int)

class Outputs:sum = Output("A + B", int)

want_main_area = False

(continues on next page)

4 Chapter 1. Getting Started

Page 9: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

def __init__(self):super().__init__()self.a = Noneself.b = None

@Inputs.adef set_A(self, a):

"""Set input 'A'."""self.a = a

@Inputs.bdef set_B(self, b):

"""Set input 'B'."""self.b = b

def handleNewSignals(self):"""Reimplemeted from OWWidget."""if self.a is not None and self.b is not None:

self.Outputs.sum.send(self.a + self.b)else:

# Clear the channel by sending `None`self.Outputs.sum.send(None)

See also:

handleNewSignals()

1.2. Defining a widget 5

Page 10: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

6 Chapter 1. Getting Started

Page 11: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

CHAPTER 2

Getting Started (Continued)

After learning what an Orange Widget is and how to define them on a toy example, we will build an semi-usefulwidgets that can work together with the existing Orange Widgets.

We will start with a very simple one, that will receive a dataset on the input and will output a dataset with 10% of thedata instances. We will call this widget OWDataSamplerA (OW for Orange Widget, DataSampler since this is whatwidget will be doing, and A since we prototype a number of this widgets in our tutorial).

2.1 A ‘Demo’ package

First in order to include our new widgets in the Orange Canvas’s toolbox we will create a dummy python projectnamed orange-demo

The layout should be:

orange-demo/setup.pyorangedemo/

__init__.pyOWDataSamplerA.py

and the orange-demo/setup.py should contain

from setuptools import setup

setup(name="Demo",packages=["orangedemo"],package_data={"orangedemo": ["icons/*.svg"]},classifiers=["Example :: Invalid"],# Declare orangedemo package to contain widgets for the "Demo" categoryentry_points={"orange.widgets": "Demo = orangedemo"},

)

7

Page 12: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

Note that we declare our orangedemo package as containing widgets from an ad hoc defined category Demo.

See also:

https://github.com/biolab/orange3/wiki/Add-Ons

Following the previous examples, our module defining the OWDataSamplerA widget starts out as:

import sysimport numpy

import Orange.datafrom Orange.widgets import widget, guifrom Orange.widgets.utils.signals import Input, Output

class OWDataSamplerA(widget.OWWidget):name = "Data Sampler"description = "Randomly selects a subset of instances from the data set"icon = "icons/DataSamplerA.svg"priority = 10

class Inputs:data = Input("Data", Orange.data.Table)

class Outputs:sample = Output("Sampled Data", Orange.data.Table)

want_main_area = False

def __init__(self):super().__init__()

# GUIbox = gui.widgetBox(self.controlArea, "Info")self.infoa = gui.widgetLabel(

box, "No data on input yet, waiting to get something.")self.infob = gui.widgetLabel(box, '')

The widget defines an input channel “Data” and an output channel called “Sampled Data”. Both will carry tokens ofthe type Orange.data.Table. In the code, we will refer to the signals as Inputs.data and Outputs.sample.

Channels can carry tokens of arbitrary types. However, the purpose of widgets is to talk with other widgets, so asone of the main design principles we try to maximize the flexibility of widgets by minimizing the number of differentchannel types. Do not invent new signal types before checking whether you cannot reuse the existing.

As our widget won’t display anything apart from some info, we will place the two labels in the control area andsurround it with the box “Info”.

The next four lines specify the GUI of our widget. This will be simple, and will include only two lines of text ofwhich, if nothing will happen, the first line will report on “no data yet”, and second line will be empty.

In order to complete our widget, we now need to define a method that will handle the input data. We will call itset_data(); the name is arbitrary, but calling the method set_<the name of the input> seems like a good practice.To designate it as the method that accepts the signal defined in Inputs.data, we decorate it with @Inputs.data.

@Inputs.datadef set_data(self, dataset):

if dataset is not None:self.infoa.setText("%d instances in input data set" % len(dataset))

(continues on next page)

8 Chapter 2. Getting Started (Continued)

Page 13: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

indices = numpy.random.permutation(len(dataset))indices = indices[:int(numpy.ceil(len(dataset) * 0.1))]sample = dataset[indices]self.infob.setText("%d sampled instances" % len(sample))self.Outputs.sample.send(sample)

else:self.infoa.setText(

"No data on input yet, waiting to get something.")self.infob.setText('')self.Outputs.sample.send(None)

The dataset argument is the token sent through the input channel which our method needs to handle.

To handle a non-empty token, the widget updates the interface reporting on number of data items on the input, thendoes the data sampling using Orange’s routines for these, and updates the interface reporting on the number of sampledinstances. Finally, the sampled data is sent as a token to the output channel defined as Output.sample.

Although our widget is now ready to test, for a final touch, let’s design an icon for our widget. As specified in thewidget header, we will call it DataSamplerA.svg and put it in icons subdirectory of orangedemo directory.

With this we can now go ahead and install the orangedemo package. We will do this by running pip install -e. command from within the orange-demo directory.

Note: Depending on your python installation you might need administrator/superuser privileges.

For a test, we now open Orange Canvas. There should be a new pane in a widget toolbox called Demo. If we clickon this pane, it displays an icon of our widget. Try to hover on it to see if the header and channel info was processedcorrectly:

2.1. A ‘Demo’ package 9

Page 14: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

Now for the real test. We put the File widget on the schema (from Data pane) and load the iris.tab dataset. We alsoput our Data Sampler widget on the scheme and open it (double click on the icon, or right-click and choose Open):

Now connect the File and Data Sampler widget (click on an output connector of the File widget, and drag the lineto the input connector of the Data Sampler). If everything is ok, as soon as you release the mouse, the connection isestablished and, the token that was waiting on the output of the file widget was sent to the Data Sampler widget, whichin turn updated its window:

10 Chapter 2. Getting Started (Continued)

Page 15: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

To see if the Data Sampler indeed sent some data to the output, connect it to the Data Table widget:

Try opening different data files (the change should propagate through your widgets and with Data Table window open,you should immediately see the result of sampling). Try also removing the connection between File and Data Sampler(right click on the connection, choose Remove). What happens to the data displayed in the Data Table?

2.1.1 Testing Your Widget Outside Orange Canvas

For debugging purposes, we want to be able to run widgets standalone: if the file with the widget code is executedas a main script, it should show the widget and feed it some suitable data. The simplest way to do so is to useOrange.widgets.utils.WidgetPreview and pass it the data for the default signal.

2.1. A ‘Demo’ package 11

Page 16: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

def main(argv=sys.argv):from AnyQt.QtWidgets import QApplicationapp = QApplication(list(argv))args = app.arguments()if len(args) > 1:

filename = args[1]else:

filename = "iris"

ow = OWDataSamplerA()ow.show()ow.raise_()

dataset = Orange.data.Table(filename)ow.set_data(dataset)ow.handleNewSignals()app.exec_()ow.set_data(None)ow.handleNewSignals()return 0

if __name__ == "__main__":sys.exit(main())

12 Chapter 2. Getting Started (Continued)

Page 17: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

CHAPTER 3

Tutorial (Settings and Controls)

In the previous section of our tutorial we have just built a simple sampling widget. Let us now make this widget a bitmore useful, by allowing a user to set the proportion of data instances to be retained in the sample. Say we want todesign a widget that looks something like this:

What we added is an Options box, with a spin entry box to set the sample size, and a check box and button to commit(send out) any change we made in setting. If the check box with “Commit data on selection change” is checked, than

13

Page 18: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

any change in the sample size will make the widget send out the sampled dataset. If datasets are large (say of severalthousands or more) instances, we may want to send out the sample data only after we are done setting the sample size,hence we left the commit check box unchecked and press “Commit” when we are ready for it.

This is a very simple interface, but there is something more to it. We want the settings (the sample size and the stateof the commit button) to be saved. That is, any change we made, we want to save it so that the next time we open thewidget the settings is there as we have left it

3.1 Widgets Settings

Luckily, since we use the base class OWWidget, the settings will be handled just fine. We only need to tell whichvariables we want to use for persistent settings.

In our widget, we will use two settings variables, and we declare this in the widget class definition (after the inputs,outputs definitions).

class OWDataSamplerB(OWWidget):name = "Data Sampler (B)"description = "Randomly selects a subset of instances from the dataset."icon = "icons/DataSamplerB.svg"priority = 20

class Inputs:data = Input("Data", Orange.data.Table)

class Outputs:sample = Output("Sampled Data", Orange.data.Table)

proportion = settings.Setting(50)commitOnChange = settings.Setting(0)

All settings have to specify their default value. When a widget is created the widget’s members are already re-stored and ready to use in its __init__ method. The contents of the two variables (self.proportion and self.commitOnChange) will be saved upon closing our widget. In our widget, we won’t be setting these variablesdirectly, but will instead use them in conjunction with GUI controls.

3.2 Controls and module gui

We will use the Orange.widgets.gui to create/define the gui. With this library, the GUI definition part of theoptions box is a bit dense but rather very short

box = gui.widgetBox(self.controlArea, "Info")self.infoa = gui.widgetLabel(

box, "No data on input yet, waiting to get something.")self.infob = gui.widgetLabel(box, "")

gui.separator(self.controlArea)self.optionsBox = gui.widgetBox(self.controlArea, "Options")gui.spin(

self.optionsBox,self,"proportion",

(continues on next page)

14 Chapter 3. Tutorial (Settings and Controls)

Page 19: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

minv=10,maxv=90,step=10,label="Sample Size [%]:",callback=[self.selection, self.checkCommit],

)gui.checkBox(

self.optionsBox, self, "commitOnChange", "Commit data on selection change")gui.button(self.optionsBox, self, "Commit", callback=self.commit)self.optionsBox.setDisabled(True)

We are already familiar with the first part - the Info group box. To make widget nicer, we put a separator betweenthis and Options box. After defining the option box, here is our first serious gui control: a Orange.widgets.gui.spin(). The first parameter specifies its parent widget/layout, in this case self.optionsBox (the resultingwidget object will automatically append itself to the parent’s layout). The second (self) and third ('proportion')define the property binding for the spin box. I.e. any change in the spin box control will automatically be propagatedto the self.proportions and vice versa - changing the value of self.proprotions in the widget code by assignment(e.g. self.proprotions = 30) will update the spin box’s state to match.

The rest of the spin box call gives some parameters for the control (minimum and maximum value and the step size),tells about the label which will be placed on the top, and tells it which functions to call when the value in the spinbox is changed. We need the first callback to make a data sample and report in the Info box what is the size of thesample, and a second callback to check if we can send this data out. In Orange.widgets.gui, callbacks are eitherreferences to functions, or a list with references, just like in our case.

With all of the above, the parameters for the call of Orange.widgets.gui.checkBox() should be clear aswell. Notice that this and a call to Orange.widgets.gui.spin() do not need a parameter which would tellthe control the value for initialization: upon construction, both controls will be set to the value that is pertained in theassociated setting variable.

That’s it. Notice though that we have, as a default, disabled all the controls in the Options box. This is because at thestart of the widget, there is no data to sample from. But this also means that when process the input tokens, we shouldtake care for enabling and disabling. The data processing and token sending part of our widget now is

@Inputs.datadef set_data(self, dataset):

if dataset is not None:self.dataset = datasetself.infoa.setText("%d instances in input dataset" % len(dataset))self.optionsBox.setDisabled(False)self.selection()

else:self.dataset = Noneself.sample = Noneself.optionsBox.setDisabled(False)self.infoa.setText("No data on input yet, waiting to get something.")self.infob.setText("")

self.commit()

def selection(self):if self.dataset is None:

return

n_selected = int(numpy.ceil(len(self.dataset) * self.proportion / 100.0))

(continues on next page)

3.2. Controls and module gui 15

Page 20: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

indices = numpy.random.permutation(len(self.dataset))indices = indices[:n_selected]self.sample = self.dataset[indices]self.infob.setText("%d sampled instances" % len(self.sample))

def commit(self):self.Outputs.sample.send(self.sample)

def checkCommit(self):if self.commitOnChange:

self.commit()

You can now also inspect the complete code of this widget. To distinguish it with a widget we have developed inthe previous section, we have designed a special icon for it. If you wish to test this widget in the Orange Canvas, putits code in the orangedemo directory we have created for the previous widget and try it out using a schema with a Fileand Data Table widget.

Well-behaved widgets remember their settings - the state of their checkboxes and radio-buttons, the text in their lineedits, the selections in their combo boxes and similar.

3.3 Persisting defaults

When a widget is removed, its settings are stored to be used as defaults for future instances of this widget.

Updated defaults are stored in user’s profile. It’s location depends on the operating system: (%APP-DATA%Orange<version>widgets on windows, ~/Library/ApplicationSupport/orange/<version>/widgets on macOS,~/.local/share/Orange/<version>/widgets on linux) Original default values can be restored by deleting files from thisfolder, by running Orange from command line with –clear-widget-settings option, or through Options/Reset WidgetSettings menu action.

3.3.1 Schema-only settings

Some settings have defaults that should not change. For instance, when using a Paint Data widget, drawn pointsshould be saved in a workflow, but a new widget should always start with a blank page - modified value should not beremembered.

This can be achieved by declaring a setting with a schema_only flag. Such setting is saved with a workflow, but itsdefault value never changes.

16 Chapter 3. Tutorial (Settings and Controls)

Page 21: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

3.4 Context dependent settings

Context dependent settings are settings which depend on the widget’s input. For instance, the scatter plot widgetcontains settings that specify the attributes for x and y axis, and the settings that define the color, shape and size of theexamples in the graph.

An even more complicated case is the widget for data selection with which one can select the examples based onvalues of certain attributes. Before applying the saved settings, these widgets needs to check their compliance withthe domain of the actual data set. To be truly useful, context dependent settings needs to save a setting configurationfor each particular dataset used. That is, when given a particular dataset, it has to select the saved settings that isapplicable and matches best currently used dataset.

Saving, loading and matching contexts is taken care of by context handlers. Currently, there are only twoclasses of context handlers implemented. The first one is the abstract ContextHandler and the second one isDomainContextHandler in which the context is defined by the dataset domain and where the settings containattribute names. The latter should cover most of your needs, while for more complicated widgets you will need toderive a new classes from it. There may even be some cases in which the context is not defined by the domain, inwhich case the ContextHandler will be used as a base for your new handler.

Contexts need to be declared, opened and closed. Opening and closing usually takes place (in the opposite order) inthe function that handles the data signal. This is how it looks in the scatter plot (the code is somewhat simplified forclarity).

@Input.datadef set_data(self, data):

self.closeContext()self.data = dataself.graph.setData(data)

self.initAttrValues()

if data is not None:self.openContext(data.domain)

self.updateGraph()self.sendSelections()

In general, the function should go like this:

• Do any clean-up you need, but without clearing any of the settings that need to be saved. Scatter plot needsnone.

• Call self.closeContext(); this ensures that all the context dependent settings (e.g. attribute names fromthe list boxes) are remembered.

• Initialize the widget state and set the controls to some defaults as if there were no context retrieving mechanism.Scatter plot does it by calling self.initAttrValues() which assigns the first two attributes to the x andy axis and the class attribute to the color. At this phase, you shouldn’t call any functions that depend on thesettings, such as drawing the graph.

• Call self.openContext(data.domain) (more about the arguments later). This will search for a suitablecontext and assign the controls new values if one is found. If there is no saved context that can be used, a newcontext is created and filled with the default values that were assigned at the previous point.

• Finally, adjust the widget according to the retrieved controls. Scatter plot now plots the graph by calling self.updateGraph().

When opening the context, we provide the arguments on which the context depends. In case ofDomainContextHandler, which scatter plot uses, we can give it a Orange.data.Domain. Whether a saved

3.4. Context dependent settings 17

Page 22: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

context can be reused is judged upon the presence of attributes in the domain.

If the widget is constructed appropriately (that is, if it strictly uses Orange.widgets.gui controls instead of theQt’s), no other administration is needed to switch the context.

Except for declaring the context settings, that is. Scatter plot has this in its class definition

settingsHandler = DomainContextHandler()attr_x = ContextSetting("")attr_y = ContextSetting("")

auto_send_selection = Setting(True)toolbar_selection = Setting(0)color_settings = Setting(None)selected_schema_index = Setting(0)

settingsHandler = DomainContextHandler() declares that Scatter plot usesDomainContextHandler. The attr_x and attr_y are declared as ContextSetting.

3.5 Migrations

At the beginning of this section of the tutorial, we created a widget with a setting called proportion, which contains avalue between 0 and 100. But imagine that for some reason, we are not satisfied with the value any more and decidethat the setting should hold a value between 0 and 1.

We update the setting’s default value, modify the appropriate code and we are done. That is, until someone that hasalready used the old version of the widget open the new one and the widget crashes. Remember, when the widget isopened, it has the same settings that were used the last time.

Is there anything we can do, as settings are replaced with saved before the __init__ function is called? There is!Migrations to the rescue.

Widget has a special attribute called settings_version. All widgets start with a settings_version of 1. When incompat-ible changes are done to the widget’s settings, its settings_version should be increased. But increasing the version byit self does not solve our problems. While the widget now knows that it uses different settings, the old ones are stillbroken and need to be updated before they can be used with the new widget. This can be accomplished by reimple-menting widget’s methods migrate_settings (for ordinary settings) and migrate_context (for context settings). Bothmethod are called with the old object and the version of the settings stored with it.

If we bumped settings_version from 1 to 2 when we did the above mentioned change, our migrate_settings methodwould look like this:

def migrate_settings(settings, version):if version < 2:

if "proportion" in settings:settings["proportion"] = settings["proportion"] / 100

Your migration rules can be simple or complex, but try to avoid simply forgetting the values, as settings are also usedin saved workflows. Imagine opening a complex workflow you have designed a year ago with the new version ofOrange and finding out that all the settings are back to default. Not fun!

Warning: If you change the format of an existing setting in a backwards-incompatible way, you will also wantto change the name of that setting. Otherwise, older versions of Orange won’t be able to load workflows with thenew setting format.

18 Chapter 3. Tutorial (Settings and Controls)

Page 23: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

There are two helper functions you can use. Orange.widget.settings.rename_settings(settings,old_name, new_name) does the obvious operation on settings, which can be either a dictionary or a context, thusit can be called from migrate_settings or migrate_context.

Another common operation may be upgrading your widget from storing variable names (as str) to storing variables(instances of classes derived from Variable). In a typical scenario, this happens when combo boxes are upgradedto using models. Function Orange.widget.settings.migrate_str_to_variable(settings,names=None) makes the necessary changes to the settings listed in names. names can be a list of setting names, asingle string or None. In the latter case, all settings that may refer to variables (that is two-elements tuples consistingof a string and an int) are migrated.

What about situations in which some context settings become inapplicable due to some changes in the widget? Forinstance, a widget that used to accept any kind of variables is modified so that it requires a numeric variable? Contextwith categorical variables will match and be reused . . . and crash the widget. In these (rare) cases, migrate_contextmust raise exception Orange.widget.settings.IncompatibleContext and the context will be removed.

So take some time, write the migrations and do not forget to bump the settings_version when you do breaking changes.

3.5. Migrations 19

Page 24: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

20 Chapter 3. Tutorial (Settings and Controls)

Page 25: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

CHAPTER 4

Channels and Tokens

Our data sampler widget was, regarding the channels, rather simple and linear: the widget was designed to receive thetoken from one widget, and send an output token to another widget. Just like in an example schema below:

There’s quite a bit more to channels and management of tokens, and we will overview most of the stuff you need toknow to make your more complex widgets in this section.

4.1 Multi-Input Channels

In essence, the basic idea about “multi-input” channels is that they can be used to connect them with several outputchannels. That is, if a widget supports such a channel, several widgets can feed their input to that widget simultane-ously.

Say we want to build a widget that takes a dataset and test various predictive modeling techniques on it. A widget hasto have an input data channel, and this we know how to deal with from our previous lesson. But, somehow differently,we want to connect any number of widgets which define learners to our testing widget. Just like in a schema below,where three different learners are used:

21

Page 26: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

We will here take a look at how we define the channels for a learning curve widget, and how we manage its inputtokens. But before we do it, just in brief: learning curve is something that you can use to test some machine learningalgorithm in trying to see how its performance depends on the size of the training set size. For this, one can drawa smaller subset of data, learn the classifier, and test it on remaining dataset. To do this in a just way (by Salzberg,1997), we perform k-fold cross validation but use only a proportion of the data for training. The output widget shouldthen look something like:

22 Chapter 4. Channels and Tokens

Page 27: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

Now back to channels and tokens. Input and output channels for our widget are defined by

class Inputs:data = Input("Data", Orange.data.Table)learner = Input("Learner", Orange.classification.Learner, multiple=True)

Notice that everything is pretty much the same as it was with widgets from previous lessons, the only differencebeing the additional argument multiple=True, which says that this input can be connected to outputs of multiplewidgets.

Handlers of multiple-input signals must accept two arguments: the sent object and the id of the sending widget.

@Inputs.learnerdef set_learner(self, learner, id):

"""Set the input learner for channel id."""if id in self.learners:

if learner is None:# remove a learner and corresponding resultsdel self.learners[id]del self.results[id]del self.curves[id]

else:# update/replace a learner on a previously connected linkself.learners[id] = learner# invalidate the cross-validation results and curve scores# (will be computed/updated in `_update`)self.results[id] = Noneself.curves[id] = None

(continues on next page)

4.1. Multi-Input Channels 23

Page 28: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

else:if learner is not None:

self.learners[id] = learner# initialize the cross-validation results and curve scores# (will be computed/updated in `_update`)self.results[id] = Noneself.curves[id] = None

if len(self.learners):self.infob.setText("%d learners on input." % len(self.learners))

else:self.infob.setText("No learners.")

self.commitBtn.setEnabled(len(self.learners))

OK, this looks like one long and complicated function. But be patient! Learning curve is not the simplest widget thereis, so there’s some extra code in the function above to manage the information it handles in the appropriate way. Tounderstand the signals, though, you should only understand the following. We store the learners (objects that learnfrom data) in an OrderedDict self.learners. This dictionary is a mapping of input id to the input value (theinput learner itself). The reason this is an OrderedDict is that the order of the input learners is important as wewant to maintain a consistent column order in the table view of the learning curve point scores.

The function above first checks if the channel id is already in self.learners and if so either deletes the corre-sponding entry if learner is None (remember receiving a None value means the link was removed/closed) or inval-idates the cross validation results and curve point for that channel id, marking for update in handleNewSignals().A similar case is when we receive a learner for a new channel id.

Note that in this widget the evaluation (k-fold cross validation) is carried out just once given the learner, dataset andevaluation parameters, and scores are then derived from class probability estimates as obtained from the evaluationprocedure. Which essentially means that switching from one to another scoring function (and displaying the result inthe table) takes only a split of a second. To see the rest of the widget, check out its code.

4.2 Using Several Output Channels

There’s nothing new here, only that we need a widget that has several output channels of the same type to illustratethe idea of the default channels in the next section. For this purpose, we will modify our sampling widget as definedin previous lessons such that it will send out the sampled data to one channel, and all other data to another channel.The corresponding channel definition of this widget is

class Outputs:sample = Output("Sampled Data", Orange.data.Table)other = Output("Other Data", Orange.data.Table)

We used this in the third incarnation of data sampler widget, with essentially the only other change in the codein the selection() and commit() functions

def selection(self):if self.dataset is None:

return

n_selected = int(numpy.ceil(len(self.dataset) * self.proportion / 100.0))indices = numpy.random.permutation(len(self.dataset))indices_sample = indices[:n_selected]

(continues on next page)

24 Chapter 4. Channels and Tokens

Page 29: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

indices_other = indices[n_selected:]self.sample = self.dataset[indices_sample]self.otherdata = self.dataset[indices_other]self.infob.setText("%d sampled instances" % len(self.sample))

def commit(self):self.Outputs.sample.send(self.sample)self.Outputs.sample.send(self.otherdata)

If a widget that has multiple channels of the same type is connected to a widget that accepts such tokens, OrangeCanvas opens a window asking the user to confirm which channels to connect. Hence, if we have just connected DataSampler (C) widget to a Data Table widget in a schema below:

we would get a following window querying users for information on which channels to connect:

4.3 Default Channels (When Using Input Channels of the Same Type)

Now, let’s say we want to extend our learning curve widget such that it does the learning the same way as it used to,but can - provided that such dataset is defined - test the learners (always) on the same, external dataset. That is, besidesthe training dataset, we need another channel of the same type but used for training dataset. Notice, however, thatmost often we will only provide the training dataset, so we would not like to be bothered (in Orange Canvas) with thedialog which channel to connect to, as the training dataset channel will be the default one.

4.3. Default Channels (When Using Input Channels of the Same Type) 25

Page 30: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

When enlisting the input channel of the same type, the default channels have a special flag in the channel specificationlist. So for our new learning curve widget, the channel specification is

class Inputs:data = Input("Data", Orange.data.Table, default=True)test_data = Input("Test Data", Orange.data.Table)learner = Input("Learner", Orange.classification.Learner, multiple=True)

That is, the Train Data channel is a single-token channel which is a default one (third parameter). Note that theflags can be added (or OR-d) together so Default + Multiple is a valid flag. To test how this works, connect afile widget to a learning curve widget and - nothing will really happen:

That is, no window with a query on which channels to connect to will open, as the default “Train Data” was selected.

4.4 Explicit Channels

Sometimes when a widget has multiple outputs of different types, some of them should not be subject to this automaticdefault connection selection. An example of this is in Orange’s Logistic Regression widget that outputs a supplemen-tary ‘Coefficients’ data table. Such outputs can be marked with and Explicit flag, which ensures they are neverselected for a default connection.

26 Chapter 4. Channels and Tokens

Page 31: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

CHAPTER 5

Responsive GUI

And now for the hard part of making the widget responsive. We will do this by offloading the learner evaluations intoa separate thread.

First read up on threading basics in Qt and in particular the subject of threads and qobjects and how they interact withthe Qt’s event loop.

We must also take special care that we can cancel/interrupt our task when the user changes algorithm parametersor removes the widget from the canvas. For that we use a strategy known as cooperative cancellation where we‘ask’ the pending task to stop executing (in the GUI thread), then in the worker thread periodically check (at knownpredetermined points) whether we should continue, and if not return early (in our case by raising an exception).

5.1 Setting up

We use Orange.widgets.utils.concurrent.ThreadExecutor for thread allocation/management (butcould easily replace it with stdlib’s concurrent.futures.ThreadPoolExecutor).

import concurrent.futuresfrom Orange.widgets.utils.concurrent import ThreadExecutor, FutureWatcher,→˓methodinvoke

We will reorganize our code to make the learner evaluation an explicit task as we will need to track its progress andstate. For this we define a Task class.

from Orange.widgets.utils.widgetpreview import WidgetPreview

class Task:"""A class that will hold the state for an learner evaluation."""

(continues on next page)

27

Page 32: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

#: A concurrent.futures.Future with our (eventual) results.#: The OWLearningCurveC class must fill this fieldfuture = ... # type: concurrent.futures.Future

#: FutureWatcher. Likewise this will be filled by OWLearningCurveCwatcher = ... # type: FutureWatcher

#: True if this evaluation has been cancelled. The OWLearningCurveC#: will setup the task execution environment in such a way that this#: field will be checked periodically in the worker thread and cancel#: the computation if so required. In a sense this is the only#: communication channel in the direction from the OWLearningCurve to the#: worker threadcancelled = False # type: bool

def cancel(self):"""Cancel the task.

Set the `cancelled` field to True and block until the future is done."""# set cancelled stateself.cancelled = True# cancel the future. Note this succeeds only if the execution has# not yet started (see `concurrent.futures.Future.cancel`) ..self.future.cancel()# ... and wait until computation finishesconcurrent.futures.wait([self.future])

In the widget’s __init__ we create an instance of the ThreadExector and initialize the task field.

#: The current evaluating task (if any)self._task = None # type: Optional[Task]#: An executor we use to submit learner evaluations into a thread poolself._executor = ThreadExecutor()

All code snippets are from OWLearningCurveC.py.

5.2 Starting a task in a thread

In handleNewSignals we call _update.

def handleNewSignals(self):self._update()

And finally the _update function (from OWLearningCurveC.py) that will start/schedule all updates.

def _update(self):if self._task is not None:

# First make sure any pending tasks are cancelled.self.cancel()

(continues on next page)

28 Chapter 5. Responsive GUI

Page 33: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

assert self._task is None

if self.data is None:return

# collect all learners for which results have not yet been computedneed_update = [

(id, learner)for id, learner in self.learners.items()if self.results[id] is None

]if not need_update:

return

At the start we cancel pending tasks if they are not yet completed. It is important to do this, we cannot allow the widgetto schedule tasks and then just forget about them. Next we make some checks and return early if there is nothing to bedone.

Continue by setting up the learner evaluations as a partial function capturing the necessary arguments:

learners = [learner for _, learner in need_update]# setup the learner evaluations as partial function capturing# the necessary arguments.if self.testdata is None:

learning_curve_func = partial(learning_curve,learners,self.data,folds=self.folds,proportions=self.curvePoints,

)else:

learning_curve_func = partial(learning_curve_with_test_data,learners,self.data,self.testdata,times=self.folds,proportions=self.curvePoints,

)

Setup the task state and the communication between the main and worker thread. The only state flowing from theGUI to the worker thread is the task.cancelled field which is a simple trip wire causing the learning_curve’s callbackargument to raise an exception. In the other direction we report the percent of work done.

# setup the task stateself._task = task = Task()# The learning_curve[_with_test_data] also takes a callback function# to report the progress. We instrument this callback to both invoke# the appropriate slots on this widget for reporting the progress# (in a thread safe manner) and to implement cooperative cancellation.set_progress = methodinvoke(self, "setProgressValue", (float,))

def callback(finished):# check if the task has been cancelled and raise an exception# from within. This 'strategy' can only be used with code that# properly cleans up after itself in the case of an exception# (does not leave any global locks, opened file descriptors, ...)

(continues on next page)

5.2. Starting a task in a thread 29

Page 34: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

if task.cancelled:raise KeyboardInterrupt()

set_progress(finished * 100)

# capture the callback in the partial functionlearning_curve_func = partial(learning_curve_func, callback=callback)

See also:

progressBarInit(), progressBarSet(), progressBarFinished()

Next, we submit the function to be run in a worker thread and instrument a FutureWatcher instance to notify us whenthe task completes (via a _task_finished slot).

self.progressBarInit()# Submit the evaluation function to the executor and fill in the# task with the resultant Future.task.future = self._executor.submit(learning_curve_func)# Setup the FutureWatcher to notify us of completiontask.watcher = FutureWatcher(task.future)# by using FutureWatcher we ensure `_task_finished` slot will be# called from the main GUI thread by the Qt's event looptask.watcher.done.connect(self._task_finished)

For the above code to work, the setProgressValue needs defined as a pyqtSlot.

@pyqtSlot(float)def setProgressValue(self, value):

assert self.thread() is QThread.currentThread()self.progressBarSet(value)

5.3 Collecting results

In _task_finished (from OWLearningCurveC.py) we handle the completed task (either success or failure) and thenupdate the displayed score table.

@pyqtSlot(concurrent.futures.Future)def _task_finished(self, f):

"""Parameters----------f : Future

The future instance holding the result of learner evaluation."""assert self.thread() is QThread.currentThread()assert self._task is not Noneassert self._task.future is fassert f.done()

self._task = Noneself.progressBarFinished()

(continues on next page)

30 Chapter 5. Responsive GUI

Page 35: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

try:results = f.result() # type: List[Results]

except Exception as ex:# Log the exception with a tracebacklog = logging.getLogger()log.exception(__name__, exc_info=True)self.error("Exception occurred during evaluation: {!r}".format(ex))# clear all resultsfor key in self.results.keys():

self.results[key] = Noneelse:

# split the combined result into per learner/model results ...results = [

list(Results.split_by_model(p_results)) for p_results in results] # type: List[List[Results]]assert all(len(r.learners) == 1 for r1 in results for r in r1)assert len(results) == len(self.curvePoints)

learners = [r.learners[0] for r in results[0]]learner_id = {learner: id_ for id_, learner in self.learners.items()}

# ... and update self.resultsfor i, learner in enumerate(learners):

id_ = learner_id[learner]self.results[id_] = [p_results[i] for p_results in results]

5.4 Stopping

Also of interest is the cancel method. Note that we also disconnect the _task_finished slot so that _task_finished doesnot receive stale results.

def cancel(self):"""Cancel the current task (if any)."""if self._task is not None:

self._task.cancel()assert self._task.future.done()# disconnect the `_task_finished` slotself._task.watcher.done.disconnect(self._task_finished)self._task = None

We also use cancel in onDeleteWidget() to stop if/when the widget is removed from the canvas.

def onDeleteWidget(self):self.cancel()super().onDeleteWidget()

5.4. Stopping 31

Page 36: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

32 Chapter 5. Responsive GUI

Page 37: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

CHAPTER 6

Utilities

6.1 Progress Bar

Operations that take more than a split second indicate their progress with a progress bar

and in the title bar of the widget’s window.

There are two mechanisms for implementing this.

6.1.1 Progress bar class

Class Orange.widgets.gui.ProgressBar is initialized with a widget and the number of iterations:

progress = Orange.widgets.gui.ProgressBar(self, n)

33

Page 38: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

6.1.2 Direct manipulation of progress bar

The progress bar can be manipulated directly through functions

• progressBarInit(self)

• progressBarSet(self, p)

• progressBarFinished(self)

progressBarInit initializes the progress bar, progressBarSet sets it to p percents (from 0 to 100), and progressBarFin-ished closes it.

The code that uses these methods must use a try-except or try-finally block to ensure that the progress bar is removedif the exception is raised.

6.2 Issuing warning and errors

Widgets can show information messages, warnings and errors. These are displayed in the top row of the widget andalso indicated in the schema.

6.2.1 Simple messages

If the widget only issues a single error, warning and/or information at a time, it can do so by calling self.error(text,shown=True), self.warning(text, shown=True) or self.information(text, shown=True). Multiple messages - but just oneof each kind - can be present at the same time:

self.warning("Discrete features are ignored.")self.error("Fitting failed due to missing data.")

At this point, the widget has a warning and an error message.

self.error(“Fitting failed due to weird data.”)

This replaces the old error message, but the warning remains.

The message is removed by setting an empty message, e.g. self.error(). To remove all messages, callself.clear_messages().

If the argument shown is set to False, the message is removed:

self.error("No suitable features", shown=not self.suitable_features)

“Not showing” a message in this way also remove any existing messages.

34 Chapter 6. Utilities

Page 39: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

6.2.2 Multiple messages

Widget that issue multiple independent messages that can appear simultaneously, need to declare them within localclasses within the widget class, and derive them from the corresponding OWWidget classes for a particular kind of amessage. For instance, a widget class can contain the following classes:

class Error(OWWidget.Error):no_continuous_features = Msg("No continuous features")

class Warning(OWWidget.Warning):empty_data = Msg("Comtrongling does not work on meta data")no_scissors_run = Msg("Do not run with scissors")ignoring_discrete = Msg("Ignoring {n} discrete features: {}")

Within the widget, errors are raised via calls like:

self.Error.no_continuous_features()self.Warning.no_scissors_run()

As for the simpler messages, the shown argument can be added:

self.Warning.no_scissors_run(shown=self.scissors_are_available)

If the message includes formatting, the call must include the necessary data for the format method:

self.Warning.ignoring_discrete(", ".join(attrs), n=len(attr))

Message is cleared by:

self.Warning.ignoring_discrete.clear()

Multiple messages can be removed as in the simpler schema, with:

self.Warning.clear()

or:

self.clear_messages()

Messages of both kinds - those from messages classes and those issued by, for instance, self.error - can coex-ist. Note, though, that methods for removing all messages of certain type (e.g. self.Error.clear()) or all messags(self.clear_message()) apply to all messages of this type.

Note: handling multiple messages through ids, that is, using self.information(id, text), self.warning(id, text) andself.error(id, text) is deprecated and will be removed in the future.

6.3 I/O Summaries

New in version 3.19.

Widgets can optionally summarize their inputs/outputs via the info namespace using the set_input_summary()and set_output_summary() methods.

self.info.set_input_summary("foo")self.info.set_output_summary("bar")

6.3. I/O Summaries 35

Page 40: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

Summaries are then displayed in the widget’s status bar:

Predefined constants indicating no input/output are available as self.info.NoInput and self.info.NoOutput respectively

self.info.set_input_summary(self.info.NoInput)self.info.set_output_summary(self.info.NoOutput)

The summaries can also contain more detailed information to be displayed in tool tip or popup:

self.info.set_output_summary("2 animals", "• 1 cat\n• 1 dog")

See also:

set_input_summary(), set_output_summary()

Note: No I/O summary messages are displayed initially. Widget authors should initialize them (to empty state) in thewidget’s __init__ method.

6.4 Tips

Widgets can provide tips about features that are not be obvious or exposed in the GUI.

Such messages are stored in widget’s class attribute UserAdviceMessages. When a widget is first shown, a messagefrom this list is selected for display. If a user accepts (clicks ‘Ok. Got it’) the choice is recorded and the message isnever shown again; just closing the message will not mark it as seen. Messages can be displayed again by pressingShift + F1.

UserAdviceMessages contains instances of Message. The messages contains a text and an id (also a string), and,optionally, an icon and an URL with further information.

The confusion matrix widget sets up the following list:

UserAdviceMessages = [widget.Message("Clicking on cells or in headers outputs the "

(continues on next page)

36 Chapter 6. Utilities

Page 41: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

"corresponding data instances","click_cell")]

6.4. Tips 37

Page 42: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

38 Chapter 6. Utilities

Page 43: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

CHAPTER 7

OWWidget

The OWWidget is the main component for implementing a widget in the Orange Canvas workflow. It both definesthe widget input/output capabilities and implements it’s functionality within the canvas.

7.1 Widget Meta Description

Every widget in the canvas framework needs to define it’s meta definition. This includes the widget’s name and textdescriptions but more importantly also its input/output specification.

class IntConstant(OWWidget):name = "Integer Constant"description = "A simple integer constant"

class Outputs:constant = Output("Constant", int)

...

def commit(self):"""Commit/send the outputs."""self.Outputs.constant.send(42)

Omitting the implementation details, this defines a simple node named Integer Constant which outputs (on a signalcalled Constant) a single object of type int.

The node’s inputs are defined similarly. Each input is then used as a decorator of its corresponding handler method,which accepts the inputs at runtime:

class Adder(OWWidget):name = "Add two integers"description = "Add two numbers"

class Inputs:(continues on next page)

39

Page 44: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

a = Input("A", int)b = Input("B", int)

class Outputs:sum = Input("A + B", int)

...

@Inputs.adef set_A(self, a):

"""Set the `A` input."""self.A = a

@Inputs.bdef set_B(self, b):

"""Set the `B` input."""self.B = b

def handleNewSignals(self):"""Coalescing update."""self.commit()

def commit(self):"""Commit/send the outputs"""sef.Outputs.sum.send("self.A + self.B)

See also:

Getting Started Tutorial

7.2 Input/Output Signal Definitions

Widgets specify their input/output capabilities in their class definitions by defining classes named Inputs and Outputs,which contain class attributes of type Input and Output, correspondingly. Input and Output require at least two ar-guments, the signal’s name (as shown in canvas) and type. Optional arguments further define the behaviour of thesignal.

Note: old-style signals define the input and output signals using class attributes inputs and outputs instead of classesInput and Output. The two attributes contain a list of tuples with the name and type and, for inputs, the name of thehandler method. The optional last argument is an integer constant giving the flags. This style of signal definition isdeprecated.

class Orange.widgets.widget.Input(name, type, id=None, doc=None, replaces=None, *, multi-ple=False, default=False, explicit=False)

Description of an input signal.

The class is used to declare input signals for a widget as follows (the example is taken from the widget Test &Score):

class Inputs:train_data = Input("Data", Table, default=True)test_data = Input("Test Data", Table)learner = Input("Learner", Learner, multiple=True)preprocessor = Input("Preprocessor", Preprocess)

Every input signal must be used to decorate exactly one method that serves as the input handler, for instance:

40 Chapter 7. OWWidget

Page 45: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

@Inputs.train_datadef set_train_data(self, data):

...

Parameters

• (str) (id) – signal name

• (type) (type) – signal type

• (str) – a unique id of the signal

• (str, optional) (doc) – signal documentation

• (list of str) (replaces) – a list with names of signals replaced by this signal

• (bool, optional) (explicit) – if set, multiple signals can be connected to thisoutput (default: False)

• (bool, optional) – when the widget accepts multiple signals of the same type, oneof them can set this flag to act as the default (default: False)

• (bool, optional) – if set, this signal is only used when it is the only option or whenexplicitly connected in the dialog (default: False)

class Orange.widgets.widget.Output(name, type, id=None, doc=None, replaces=None, *, de-fault=False, explicit=False, dynamic=True)

Description of an output signal.

The class is used to declare output signals for a widget as follows (the example is taken from the widget Test &Score):

class Outputs:predictions = Output("Predictions", Table)evaluations_results = Output("Evaluation Results", Results)

The signal is then transmitted by, for instance:

self.Outputs.predictions.send(predictions)

Parameters

• (str) (id) – signal name

• (type) (type) – signal type

• (str) – a unique id of the signal

• (str, optional) (doc) – signal documentation

• (list of str) (replaces) – a list with names of signals replaced by this signal

• (bool, optional) (dynamic) – when the widget accepts multiple signals of the sametype, one of them can set this flag to act as the default (default: False)

• (bool, optional) – if set, this signal is only used when it is the only option or whenexplicitly connected in the dialog (default: False)

• (bool, optional) – Specifies that the instances on the output will in general be sub-types of the declared type and that the output can be connected to any input signal whichcan accept a subtype of the declared output type (default: True)

7.2. Input/Output Signal Definitions 41

Page 46: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

7.3 Sending/Receiving

The widgets receive inputs at runtime with the handler method decorated with the signal, as shown in the aboveexamples.

If an input is defined with the flag multiple set, the input handler method also receives a connection id uniquelyidentifying a connection/link on which the value was sent (see also Channels and Tokens)

The widget sends an output by calling the signal’s send method, as shown above.

7.4 Accessing Controls though Attribute Names

The preferred way for constructing the user interface is to use functions from module Orange.widgets.gui thatinsert a Qt widget and establish the signals for synchronization with the widget’s attributes.

gui.checkBox(box, self, “binary_trees”, “Induce binary tree”)

This inserts a QCheckBox into the layout of box, and make it reflect and changes the attriubte self.binary_trees. Theinstance of QCheckbox can be accessed through the name it controls. E.g. we can disable the check box by calling

self.controls.binary_trees.setDisabled(True)

This may be more practical than having to store the attribute and the Qt widget that controls it, e.g. with

self.binarization_cb = gui.checkBox( box, self, “binary_trees”, “Induce binary tree”)

7.5 Class Member Documentation

class Orange.widgets.widget.OWWidget(*args, **kwargs)OWBaseWidget extended with Orange.data.Table related report methods (Report)

class Orange.widgets.widget.Message(text, persistent_id, icon=None, moreurl=None)A user message.

Parameters

• text (str) – Message text

• persistent_id (str) – A persistent message id.

• icon (QIcon or QStyle.StandardPixmap) – Message icon

• moreurl (str) – An url to open when a user clicks a ‘Learn more’ button.

See also:

OWBaseWidget.UserAdviceMessages

class Orange.widgets.widget.StateInfo(*args, **kwargs)A namespace for OWBaseWidget’s detailed input/output/state summary reporting.

See also:

OWBaseWidget.info

class Summary(brief=”, details=”, icon=<PyQt5.QtGui.QIcon object>, format=0)Input/output summary description.

This class is used to hold and report detailed I/O summaries.

42 Chapter 7. OWWidget

Page 47: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

briefA brief (inline) description.

Type str

detailsA richer detailed description.

Type str

iconAn custom icon. If not set a default set will be used to indicate special states (i.e. empty input . . . )

Type QIcon

formatQt.PlainText if brief and details are to be rendered as plain text or Qt.RichText if they are HTML.

Type Qt.TextFormat

See also:

StateInfo.set_input_summary(), StateInfo.set_output_summary(),StateInfo.Empty , StateInfo.Partial, Supported HTML Subset

classmethod default_icon(role)Return a default icon for input/output role.

Parameters role (str) – “input” or “output”Returns iconReturn type QIcon

class Empty(brief=”, details=”, icon=<PyQt5.QtGui.QIcon object>, format=0)Bases: orangewidget.widget.Summary

Input/output summary description indicating empty I/O state.

class Partial(brief=”, details=”, icon=<PyQt5.QtGui.QIcon object>, format=0)Bases: orangewidget.widget.Summary

Input summary indicating partial input.

This state indicates that some inputs are present but more are needed in order for the widget to proceed.

NoInput Empty()A default message displayed to indicate no inputs.

NoOutput Empty()A default message displayed to indicate no output.

set_input_summary(summary: Optional[StateInfo.Summary]])Set the input summary description.

Parameters summary (Optional[StateInfo.Summary]) –

set_input_summary(brief:str, detailed:str="", icon:QIcon=QIcon, for-mat:Qt.TextFormat=Qt.PlainText)

set_output_summary(summary: Optional[StateInfo.Summary]])Set the output summary description.

Parameters summary (Optional[StateInfo.Summary]) –

set_output_summary(brief:str, detailed:str="", icon:QIcon=QIcon, for-mat:Qt.TextFormat=Qt.PlainText)

input_summary_changed(message: StateInfo.Message)Signal emitted when the input summary changes

7.5. Class Member Documentation 43

Page 48: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

output_summary_changed(message: StateInfo.Message)Signal emitted when the output summary changes

44 Chapter 7. OWWidget

Page 49: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

CHAPTER 8

Library of Common GUI Controls

gui is a library of functions which allow constructing a control (like check box, line edit or a combo), inserting itinto the parent’s layout, setting tooltips, callbacks and so forth, establishing synchronization with a Python object’sattribute (including saving and retrieving when the widgets is closed and reopened) . . . in a single call.

Almost all functions need three arguments:

• the widget into which the control is inserted,

• the master widget with one whose attributes the control’s value is synchronized,

• the name of that attribute (value).

All other arguments should be given as keyword arguments for clarity and also for allowing the potential futurecompatibility-breaking changes in the module. Several arguments that are common to all functions must always begiven as keyword arguments.

8.1 Common options

All controls accept the following arguments that can only be given as keyword arguments.

tooltip A string for a tooltip that appears when mouse is over the control.

disabled Tells whether the control be disabled upon the initialization.

addSpace Gives the amount of space that is inserted after the control (or the box that encloses it). IfTrue, a space of 8 pixels is inserted. Default is 0.

addToLayout The control is added to the parent’s layout unless this flag is set to False.

stretch The stretch factor for this widget, used when adding to the layout. Default is 0.

sizePolicy The size policy for the box or the control.

45

Page 50: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

8.2 Common Arguments

Many functions share common arguments.

widget Widget on which control will be drawn.

master Object which includes the attribute that is used to store the control’s value; most often the self ofthe widget into which the control is inserted.

value String with the name of the master’s attribute that synchronizes with the the control’s value..

box Indicates if there should be a box that around the control. If box is False (default), no box is drawn;if it is a string, it is also used as the label for the box’s name; if box is any other true value (such asTrue :), an unlabeled box is drawn.

callback A function that is called when the state of the control is changed. This can be a single functionor a list of functions that will be called in the given order. The callback function should not changethe value of the controlled attribute (the one given as the value argument described above) to avoida cycle (a workaround is shown in the description of listBox function.

label A string that is displayed as control’s label.

labelWidth The width of the label. This is useful for aligning the controls.

orientation When the label is given used, this argument determines the relative placement of the labeland the control. Label can be above the control, (“vertical” or True - this is the default) or in thesame line with control, (“horizontal” or False). Orientation can also be an instance of QLayout.

8.3 Properties

PyQt support settings of properties using keyword arguments. Functions in this module mimic this functionality. Forinstance, calling

cb = gui.comboBox(. . . , editable=True)

has the same effect as

cb = gui.comboBox(. . . ) cb.setEditable(True)

Any properties that have the corresponding setter in the underlying Qt control can be set by using keyword arguments.

8.4 Common Attributes

box If the constructed widget is enclosed into a box, the attribute box refers to the box.

8.5 Widgets

This section describes the wrappers for controls like check boxes, buttons and similar. Using them is preferred overcalling Qt directly, for convenience, readability, ease of porting to newer versions of Qt and, in particular, because theyset up a lot of things that happen in behind.

Orange.widgets.gui.checkBox(widget, master, value, label, box=None, callback=None, getwid-get=False, id_=None, labelWidth=None, disables=None, state-WhenDisabled=None, **misc)

A simple checkbox.

46 Chapter 8. Library of Common GUI Controls

Page 51: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

Parameters

• widget (QWidget or None) – the widget into which the box is inserted

• master (OWBaseWidget or OWComponent) – master widget

• value (str) – the master’s attribute with which the value is synchronized

• label (str) – label

• box (int or str or None) – tells whether the widget has a border, and its label

• callback (function) – a function that is called when the check box state is changed

• getwidget (bool) – If set True, the callback function will get a keyword argument widgetreferencing the check box

• id (any) – If present, the callback function will get a keyword argument id with this value

• labelWidth (int) – the width of the label

• disables (list or QWidget or None) – a list of widgets that are disabled if thecheck box is unchecked

• stateWhenDisabled (bool or Qt.CheckState or None) – the shown state ofthe checkbox when it is disabled (default: None, unaffected)

Returns constructed check box; if is is placed within a box, the box is return in the attribute box

Return type QCheckBox

Orange.widgets.gui.lineEdit(widget, master, value, label=None, labelWidth=None, orientation=2,box=None, callback=None, valueType=None, validator=None, con-trolWidth=None, callbackOnType=False, focusInCallback=None,**misc)

Insert a line edit.

Parameters

• widget (QWidget or None) – the widget into which the box is inserted

• master (OWBaseWidget or OWComponent) – master widget

• value (str) – the master’s attribute with which the value is synchronized

• label (str) – label

• labelWidth (int) – the width of the label

• orientation (Qt.Vertical (default) or Qt.Horizontal) – tells whether to put the labelabove or to the left

• box (int or str or None) – tells whether the widget has a border, and its label

• callback (function) – a function that is called when the check box state is changed

• valueType (type) –

the type into which the entered string is converted when synchronizing to value. Ifomitted, the type of the current

value is used. If value is None, the text is left as a string.

• validator (QValidator) – the validator for the input

• controlWidth (int) – the width of the line edit

• callbackOnType (bool) – if set to True, the callback is called at each key press (default:False)

8.5. Widgets 47

Page 52: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

• focusInCallback (function) – a function that is called when the line edit receivesfocus

Return type QLineEdit or a box

Orange.widgets.gui.listBox(widget, master, value=None, labels=None, box=None, call-back=None, selectionMode=1, enableDragDrop=False, drag-DropCallback=None, dataValidityCallback=None, sizeHint=None,**misc)

Insert a list box.

The value with which the box’s value synchronizes (master.<value>) is a list of indices of selected items.

Parameters

• widget (QWidget or None) – the widget into which the box is inserted

• master (OWWidget or OWComponent) – master widget

• value (str) – the name of the master’s attribute with which the value is synchronized (listof ints - indices of selected items)

• labels (str) – the name of the master’s attribute with the list of items (as strings or tupleswith icon and string)

• box (int or str or None) – tells whether the widget has a border, and its label

• callback (function) – a function that is called when the selection state is changed

• selectionMode (QAbstractItemView.SelectionMode) – selection mode - sin-gle, multiple etc

• enableDragDrop (bool) – flag telling whether drag and drop is available

• dragDropCallback (function) – callback function on drop event

• dataValidityCallback (function) – function that check the validity on enter andmove event; it should return either ev.accept() or ev.ignore().

• sizeHint (QSize) – size hint

Return type OrangeListBox

Orange.widgets.gui.comboBox(*args, **kwargs)

Orange.widgets.gui.radioButtonsInBox(widget, master, value, btnLabels=(), tooltips=None,box=None, label=None, orientation=2, call-back=None, **misc)

Construct a button group and add radio buttons, if they are given. The value with which the buttons synchronizeis the index of selected button.

Parameters

• widget (QWidget or None) – the widget into which the box is inserted

• master (OWBaseWidget or OWComponent) – master widget

• value (str) – the master’s attribute with which the value is synchronized

• btnLabels (list of str or pixmaps) – a list of labels or icons for radio buttons

• tooltips (list of str) – a list of tool tips of the same length as btnLabels

• box (int or str or None) – tells whether the widget has a border, and its label

• label (str) – a label that is inserted into the box

• callback (function) – a function that is called when the selection is changed

48 Chapter 8. Library of Common GUI Controls

Page 53: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

• orientation (Qt.Vertical (default), Qt.Horizontal or an instance of QLayout) – orienta-tion of the box

Return type QButtonGroup

Orange.widgets.gui.appendRadioButton(group, label, insertInto=None, disabled=False,tooltip=None, sizePolicy=None, addToLayout=True,stretch=0, addSpace=False, id=None)

Construct a radio button and add it to the group. The group must be constructed with radioButtons since itadds additional attributes need for the call backs.

The radio button is inserted into insertInto or, if omitted, into the button group. This is useful for more complexgroups, like those that have radio buttons in several groups, divided by labels and inside indented boxes.

Parameters

• group (QButtonGroup) – the button group

• label (str or QPixmap) – string label or a pixmap for the button

• insertInto (QWidget) – the widget into which the radio button is inserted

Return type QRadioButton

Orange.widgets.gui.spin(widget, master, value, minv, maxv, step=1, box=None, label=None,labelWidth=None, orientation=1, callback=None, controlWidth=None,callbackOnReturn=False, checked=None, checkCallback=None, post-text=None, disabled=False, alignment=1, keyboardTracking=True, deci-mals=None, spinType=<class ’int’>, **misc)

A spinbox with lots of bells and whistles, such as a checkbox and various callbacks. It constructs a control oftype SpinBoxWFocusOut or DoubleSpinBoxWFocusOut.

Parameters

• widget (QWidget or None) – the widget into which the box is inserted

• master (OWBaseWidget or OWComponent) – master widget

• value (str) – the master’s attribute with which the value is synchronized

• minv (int or float) – minimal value

• maxv (int or float) – maximal value

• step (int or float) – step (default: 1)

• box (int or str or None) – tells whether the widget has a border, and its label

• label (str) – label that is put in above or to the left of the spin box

• labelWidth (int) – optional label width (default: None)

• orientation (Qt.Horizontal (default), Qt.Vertical or instance of QLayout) – tellswhether to put the label above or to the left

• callback (function) – a function that is called when the value is entered; ifcallbackOnReturn is True, the function is called when the user commits the valueby pressing Enter or clicking the icon

• controlWidth (int) – the width of the spin box

• callbackOnReturn (bool) – if True, the spin box has an associated icon that must beclicked to confirm the value (default: False)

8.5. Widgets 49

Page 54: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

• checked (str) – if not None, a check box is put in front of the spin box; when unchecked,the spin box is disabled. Argument checked gives the name of the master’s attribute givenwhose value is synchronized with the check box’s state (default: None).

• checkCallback (function) – a callback function that is called when the check box’sstate is changed

• posttext (str) – a text that is put to the right of the spin box

• alignment (Qt.Alignment) – alignment of the spin box (e.g. Qt.AlignLeft)

• keyboardTracking (bool) – If True, the valueChanged signal is emitted when the useris typing (default: True)

• spinType (type) – determines whether to use QSpinBox (int) or QDoubleSpinBox(float)

• decimals (int) – number of decimals (if spinType is float)

Returns Tuple (spin box, check box) if ‘checked is True, otherwise the spin box

Return type tuple or gui.SpinBoxWFocusOut

Orange.widgets.gui.doubleSpin(widget, master, value, minv, maxv, step=1, box=None, la-bel=None, labelWidth=None, orientation=1, callback=None,controlWidth=None, callbackOnReturn=False, checked=None,checkCallback=None, posttext=None, alignment=1, keyboard-Tracking=True, decimals=None, **misc)

Backward compatilibity function: calls spin with spinType=float.

Orange.widgets.gui.hSlider(widget, master, value, box=None, minValue=0, maxValue=10,step=1, callback=None, callback_finished=None, label=None, la-belFormat=’ %d’, ticks=False, divideFactor=1.0, vertical=False, cre-ateLabel=True, width=None, intOnly=True, **misc)

Construct a slider.

Parameters

• widget (QWidget or None) – the widget into which the box is inserted

• master (OWBaseWidget or OWComponent) – master widget

• value (str) – the master’s attribute with which the value is synchronized

• box (int or str or None) – tells whether the widget has a border, and its label

• label (str) – a label that is inserted into the box

• callback (function) – a function that is called when the value is changed

• callback_finished (function) – a function that is called when the slider valuestopped changing for at least 500 ms or when the slider is released

• minValue (int or float) – minimal value

• maxValue (int or float) – maximal value

• step (int or float) – step size

• labelFormat (str) – the label format; default is ” %d”

• ticks (bool) – if set to True, ticks are added below the slider

• divideFactor (float) – a factor with which the displayed value is divided

• vertical (bool) – if set to True, the slider is vertical

50 Chapter 8. Library of Common GUI Controls

Page 55: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

• createLabel (bool) – unless set to False, labels for minimal, maximal and the currentvalue are added to the widget

• width (int) – the width of the slider

• intOnly (bool) – if True, the slider value is integer (the slider is of type QSlider)otherwise it is float (FloatSlider, derived in turn from QSlider).

Return type QSlider or FloatSlider

Orange.widgets.gui.button(widget, master, label, callback=None, width=None, height=None, tog-gleButton=False, value=”, default=False, autoDefault=True, button-Type=<class ’PyQt5.QtWidgets.QPushButton’>, **misc)

Insert a button (QPushButton, by default)

Parameters

• widget (QWidget or None) – the widget into which the button is inserted

• master (OWBaseWidget or OWComponent) – master widget

• label (str) – label

• callback (function) – a function that is called when the button is pressed

• width (int) – the width of the button

• height (int) – the height of the button

• toggleButton (bool) – if set to True, the button is checkable, but it is not synchronizedwith any attribute unless the value is given

• value (str) – the master’s attribute with which the value is synchronized (the argumentis optional; if present, it makes the button “checkable”, even if toggleButton is not set)

• default (bool) – if True it makes the button the default button; this is the button that isactivated when the user presses Enter unless some auto default button has current focus

• autoDefault (bool) – all buttons are auto default: they are activated if they have focus(or are the next in the focus chain) when the user presses enter. By setting autoDefault toFalse, the button is not activated on pressing Return.

• buttonType (QPushButton) – the button type (default: QPushButton)

Return type QPushButton

Orange.widgets.gui.toolButton(widget, master, label=”, callback=None, width=None,height=None, tooltip=None)

Insert a tool button. Calls button

Parameters

• widget (QWidget or None) – the widget into which the button is inserted

• master (OWBaseWidget or OWComponent) – master widget

• label (str) – label

• callback (function) – a function that is called when the button is pressed

• width (int) – the width of the button

• height (int) – the height of the button

Return type QToolButton

Orange.widgets.gui.widgetLabel(widget, label=”, labelWidth=None, **misc)Construct a simple, constant label.

8.5. Widgets 51

Page 56: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

Parameters

• widget (QWidget or None) – the widget into which the box is inserted

• label (str) – The text of the label (default: None)

• labelWidth (int) – The width of the label (default: None)

Returns Constructed label

Return type QLabel

Orange.widgets.gui.label(widget, master, label, labelWidth=None, box=None, orientation=2,**misc)

Construct a label that contains references to the master widget’s attributes; when their values change, the labelis updated.

Argument label is a format string following Python’s syntax (see the corresponding Python documentation):the label’s content is rendered as label % master.__dict__. For instance, if the label is given as “There are%(mm)i monkeys”, the value of master.mm (which must be an integer) will be inserted in place of %(mm)i.

Parameters

• widget (QWidget or None) – the widget into which the box is inserted

• master (OWBaseWidget or OWComponent) – master widget

• label (str) – The text of the label, including attribute names

• labelWidth (int) – The width of the label (default: None)

• orientation (Qt.Vertical (default), Qt.Horizontal or instance of QLayout) – layout ofthe inserted box

Returns label

Return type QLabel

8.6 Other widgets

Orange.widgets.gui.widgetBox(widget, box=None, orientation=2, margin=None, spacing=4,**misc)

Construct a box with vertical or horizontal layout, and optionally, a border with an optional label.

If the widget has a frame, the space after the widget is added unless explicitly disabled.

Parameters

• widget (QWidget or None) – the widget into which the box is inserted

• box (int or str or None) – tells whether the widget has a border, and its label

• orientation (Qt.Horizontal, Qt.Vertical or instance of QLayout) – orientation of thebox

• sizePolicy (QSizePolicy) – The size policy for the widget (default: None)

• margin (int) – The margin for the layout. Default is 7 if the widget has a border, and 0 ifnot.

• spacing (int) – Spacing within the layout (default: 4)

Returns Constructed box

Return type QGroupBox or QWidget

52 Chapter 8. Library of Common GUI Controls

Page 57: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

Orange.widgets.gui.indentedBox(widget, sep=20, orientation=2, **misc)Creates an indented box. The function can also be used “on the fly”:

gui.checkBox(gui.indentedBox(box), self, "spam", "Enable spam")

To align the control with a check box, use checkButtonOffsetHint:

gui.hSlider(gui.indentedBox(self.interBox), self, "intervals")

Parameters

• widget (QWidget) – the widget into which the box is inserted

• sep (int) – Indent size (default: 20)

• orientation (Qt.Vertical (default), Qt.Horizontal or instance of QLayout) – orientationof the inserted box

Returns Constructed box

Return type QGroupBox or QWidget

Orange.widgets.gui.separator(widget, width=4, height=4)Add a separator of the given size into the widget.

Parameters

• widget (QWidget) – the widget into whose layout the separator is added

• width (int) – width of the separator

• height (int) – height of the separator

Returns separator

Return type QWidget

Orange.widgets.gui.rubber(widget)Insert a stretch 100 into the widget’s layout

8.7 Utility functions

Orange.widgets.gui.attributeIconDict = {}A dict that returns icons for different attribute types. The dict is constructed on first use since icons cannot becreated before initializing the application.

Accepted keys are variable type codes and instances of Orange.data.Variable: attributeIconDict[var]will give the appropriate icon for variable var or a question mark if the type is not recognized

Orange.widgets.gui.attributeItem(var)Construct a pair (icon, name) for inserting a variable into a combo or list box

Parameters var (Orange.data.Variable) – variable

Return type tuple with QIcon and str

8.7. Utility functions 53

Page 58: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

8.8 Internal functions and classes

This part of documentation describes some classes and functions that are used internally. The classes will likelymaintain compatibility in the future, while the functions may be changed.

8.8.1 Wrappers for Qt classes

class Orange.widgets.gui.SpinBoxWFocusOut(minv, maxv, step, parent=None)A class derived from QSpinBox, which postpones the synchronization of the control’s value with the master’sattribute until the control looses focus or user presses Tab when the value has changed.

The class overloads onChange event handler to show the commit button, and onEnter to commit the changewhen enter is pressed.

class Orange.widgets.gui.DoubleSpinBoxWFocusOut(minv, maxv, step, parent)Same as SpinBoxWFocusOut, except that it is derived from QDoubleSpinBox

class Orange.widgets.gui.LineEditWFocusOut(parent, callback, focusInCallback=None)A class derived from QLineEdit, which postpones the synchronization of the control’s value with the master’sattribute until the user leaves the line edit or presses Tab when the value is changed.

The class also allows specifying a callback function for focus-in event.

callbackCallback that is called when the change is confirmed

focusInCallbackCallback that is called on the focus-in event

class Orange.widgets.gui.OrangeListBox(master, enableDragDrop=False, dragDropCall-back=None, dataValidityCallback=None, size-Hint=None, *args)

List box with drag and drop functionality. Function listBox constructs instances of this class; do not use theclass directly.

masterThe widget into which the listbox is inserted.

ogLabelsThe name of the master’s attribute that holds the strings with items in the list box.

ogValueThe name of the master’s attribute that holds the indices of selected items.

enableDragDropA flag telling whether drag-and-drop is enabled.

dragDropCallbackA callback that is called at the end of drop event.

dataValidityCallbackA callback that is called on dragEnter and dragMove events and returns either ev.accept() or ev.ignore().

defaultSizeHintThe size returned by the sizeHint method.

54 Chapter 8. Library of Common GUI Controls

Page 59: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

8.8.2 Wrappers for Python classes

class Orange.widgets.gui.ControlledList(content, listBox=None)A class derived from a list that is connected to a QListBox: the list contains indices of items that are selectedin the list box. Changing the list content changes the selection in the list box.

8.8.3 Other functions

Orange.widgets.gui.miscellanea(control, box, parent, addToLayout=True, stretch=0, sizePol-icy=None, addSpace=False, disabled=False, tooltip=None,**kwargs)

Helper function that sets various properties of the widget using a common set of arguments.

The function - sets the control’s attribute box, if box is given and control.box is not yet set, - attaches a tool tipto the control if specified, - disables the control, if disabled is set to True, - adds the box to the parent’s layoutunless addToLayout is set to False; the stretch factor can be specified, - adds the control into the box’s layoutif the box is given (regardless of addToLayout!) - sets the size policy for the box or the control, if the policy isgiven, - adds space in the parent’s layout after the box if addSpace is set and addToLayout is not False.

If box is the same as parent it is set to None; this is convenient because of the way complex controls are inserted.

Unused keyword arguments are assumed to be properties; with this gui function mimic the behaviour of PyQt’sconstructors. For instance, if gui.lineEdit is called with keyword argument sizePolicy=some_policy, miscalleneawill call control.setSizePolicy(some_policy).

Parameters

• control (QWidget) – the control, e.g. a QCheckBox

• box (QWidget or None) – the box into which the widget was inserted

• parent (QWidget) – the parent into whose layout the box or the control will be inserted

• addSpace (bool or int) – the amount of space to add after the widget

• disabled (bool) – If set to True, the widget is initially disabled

• addToLayout (bool) – If set to False the widget is not added to the layout

• stretch (int) – the stretch factor for this widget, used when adding to the layout (default:0)

• tooltip (str or None) – tooltip that is attached to the widget

• sizePolicy (QSizePolicy) – the size policy for the box or the control

Orange.widgets.gui.setLayout(widget, layout)Set the layout of the widget.

If layout is given as Qt.Vertical or Qt.Horizontal, the function sets the layout to QVBoxLayout orQVBoxLayout.

Parameters

• widget (QWidget) – the widget for which the layout is being set

• layout (Qt.Horizontal, Qt.Vertical or instance of QLayout) – layout

Orange.widgets.gui.createAttributePixmap(char, background=2, color=3)Create a QIcon with a given character. The icon is 13 pixels high and wide.

Parameters

• char (str) – The character that is printed in the icon

8.8. Internal functions and classes 55

Page 60: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

• background (QColor) – the background color (default: black)

• color (QColor) – the character color (default: white)

Return type QIcon

56 Chapter 8. Library of Common GUI Controls

Page 61: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

CHAPTER 9

Debugging and testing

9.1 Running widgets as scripts

To run a widget without canvas - for debugging and for nitpicking about the GUI - the widget module must beexecutable as a script. This is handled by WidgetPreview . It is typically used as follows

if __name__ == "__main__":WidgetPreview(OWMyWidgetName).run()

where OWMyWidgetName is the widget’s class.

We can also pass the data to the widget. For instance,

if __name__ == "__main__":WidgetPreview(OWMyWidgetName).run(Orange.data.Table("iris"))

passes the Iris data set to the widget. Passing data in this way requires that there is a single or default signal for theargument’s data type. Multiple signals can be passed as keyword arguments in which the names correspond to signalhandlers:

if __name__ == "__main__":data = Orange.data.Table("iris")WidgetPreview(OWScatterPlot).run(

set_data=data,set_subset_data=data[:30]

)

If the signal handler accepts multiple inputs, they can be passed as a list, like in the following method in the Tablewidget.

if __name__ == "__main__":WidgetPreview(OWDataTable).run(

[(Table("iris"), "iris"),(Table("brown-selected"), "brown-selected"),

(continues on next page)

57

Page 62: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

(continued from previous page)

(Table("housing"), "housing")]

)

Preview ends by tearing down the widget and calling sys.exit with the widget’s exit code. This can be preventedby adding a no_exit=True argument. We can also prevent showing the widget and starting the event loop by usingno_exec=True. This, together with some previewers method described below, can be used for debugging the widget.For example, OWRank’s preview,

if __name__ == "__main__":from Orange.classification import RandomForestLearnerWidgetPreview(OWRank).run(

set_learner=(RandomForestLearner(), (3, 'Learner', None)),set_data=Table("heart_disease.tab"))

can be temporarily modified to

if __name__ == "__main__":from Orange.classification import RandomForestLearnerpreviewer = WidgetPreview(OWRank)previewer.run(Table("heart_disease.tab"), no_exit=True)previewer.send_signals(

set_learner=(RandomForestLearner(), (3, 'Learner', None)))previewer.run()

which shows the widget twice, allows us a finer control of signal passing, and offers adding some breakpoints.

class Orange.widgets.utils.widgetpreview.WidgetPreview(widget_cls)A helper class for widget previews.

widgetan instance of the widget or None

Type OWBaseWidget

widget_clsthe widget class

Type type

run(input_data=None, *, no_exec=False, no_exit=False, **kwargs)Run a preview of the widget;

It first creates a widget, unless it exists from the previous call. This can only happen if no_exit was set toTrue.

Next, it passes the data signals to the widget. Data given as positional argument must be of a type forwhich there exist a single or a default handler. Signals can also be given by keyword arguments, wherethe name of the argument is the name of the handler method. If the data is a list of tuples, the sequence oftuples is sent to the same handler.

Next, the method shows the widget and starts the event loop, unless no_exec argument is set to True.

Finally, unless the argument no_exit is set to True, the method tears down the widget, deletes the referenceto the widget and calls Python’s garbage collector, as an effort to catch any crashes due to widget members(typically QGraphicsScene elements) outliving the widget. It then calls sys.exit with the exit codefrom the application’s main loop.

If no_exit is set to True, the run keeps the widget alive. In this case, subsequent calls to run or othermethods (send_signals, exec_widget) will use the same widget.

58 Chapter 9. Debugging and testing

Page 63: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

Parameters

• input_data – data used for the default input signal of matching type

• no_exec (bool) – if set to True, the widget is not shown and the event loop is not started

• no_exit (bool) – if set to True, the widget is not torn down

• **kwargs – data for input signals

create_widget()Initialize QApplication and construct the widget.

send_signals(input_data=None, **kwargs)Send signals to the widget

exec_widget()Show the widget and start the QApplication’s main loop.

tear_down()Save settings and delete the widget.

9.2 Unit-testing Widgets

Orange provides a base class WidgetTest with helper methods for unit testing.

class Orange.widgets.tests.base.WidgetTest(methodName=’runTest’)

assert_domain_equal(domain1, domain2)Test domains for equality.

Unlike in domain1 == domain2 uses Variable.__eq__, which in case of DiscreteVariable ignores values,this method also checks that both domain have equal values.

9.2. Unit-testing Widgets 59

Page 64: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

60 Chapter 9. Debugging and testing

Page 65: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

CHAPTER 10

API

10.1 Orange.widgets.utils.concurrent

General helper functions and classes for PyQt concurrent programming

class Orange.widgets.utils.concurrent.ThreadExecutor(parent=None, thread-Pool=None, **kwargs)

Bases: PyQt5.QtCore.QObject, concurrent.futures._base.Executor

ThreadExecutor object class provides an interface for running tasks in a QThreadPool.

Parameters

• parent (QObject) – Executor’s parent instance.

• threadPool (Optional[QThreadPool]) – Thread pool to be used by the instanceof the Executor. If None then a private global thread pool will be used.

Changed in version 3.15: Before 3.15 a QThreadPool.globalPool() was used as the default.

Warning: If you pass a custom QThreadPool make sure it creates threads with sufficientstack size for the tasks submitted to the executor (see QThreadPool.setStackSize).

submit(func, *args, **kwargs)Reimplemented from concurrent.futures.Executor

Schedule the func(*args, **kwargs) to be executed and return an Future instance representing the resultof the computation.

shutdown(wait=True)Shutdown the executor and free all resources. If wait is True then wait until all pending futures are executedor cancelled.

class Orange.widgets.utils.concurrent.FutureWatcher(future=None, parent=None,**kwargs)

Bases: PyQt5.QtCore.QObject, orangewidget.utils.concurrent.PyOwned

61

Page 66: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

An QObject watching the state changes of a concurrent.futures.Future

Note: The state change notification signals (done, finished, . . . ) are always emitted when the control flowreaches the event loop (even if the future is already completed when set).

Note: An event loop must be running, otherwise the notifier signals will not be emitted.

Parameters

• parent (QObject) – Parent object.

• future (Future) – The future instance to watch.

Example

>>> app = QCoreApplication.instance() or QCoreApplication([])>>> f = submit(lambda i, j: i ** j, 10, 3)>>> watcher = FutureWatcher(f)>>> watcher.resultReady.connect(lambda res: print("Result:", res))>>> watcher.done.connect(app.quit)>>> _ = app.exec()Result: 1000>>> f.result()1000

done(future: Future)Signal emitted when the future is done (cancelled or finished)

finished(future: Future)Signal emitted when the future is finished (i.e. returned a result or raised an exception - but not if cancelled)

cancelled(future: Future)Signal emitted when the future was cancelled

resultReady(result: Any)Signal emitted with the future’s result when successfully finished.

exceptionReady(exception: BaseException)Signal emitted with the future’s exception when finished with an exception.

setFuture(future)Set the future to watch.

Raise a RuntimeError if a future is already set.

Parameters future (Future) –

future()Return the future instance.

result()Return the future’s result.

Note: This method is non-blocking. If the future has not yet completed it will raise an error.

62 Chapter 10. API

Page 67: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

exception()Return the future’s exception.

Note: This method is non-blocking. If the future has not yet completed it will raise an error.

customEvent(self, QEvent)

class Orange.widgets.utils.concurrent.FutureSetWatcher(futures=None, *args,**kwargs)

Bases: PyQt5.QtCore.QObject, orangewidget.utils.concurrent.PyOwned

An QObject watching the state changes of a list of concurrent.futures.Future instances

Note: The state change notification signals (doneAt, finishedAt, . . . ) are always emitted when the control flowreaches the event loop (even if the future is already completed when set).

Note: An event loop must be running, otherwise the notifier signals will not be emitted.

Parameters

• parent (QObject) – Parent object.

• futures (List[Future]) – A list of future instance to watch.

Example

>>> app = QCoreApplication.instance() or QCoreApplication([])>>> fs = [submit(lambda i, j: i ** j, 10, 3) for i in range(10)]>>> watcher = FutureSetWatcher(fs)>>> watcher.resultReadyAt.connect(... lambda i, res: print("Result at {}: {}".format(i, res))... )>>> watcher.doneAll.connect(app.quit)>>> _ = app.exec()Result at 0: 1000...

doneAt(index: int, future: Future)Signal emitted when the future at index is done (cancelled or finished)

finishedAt(index: int, future: Future)Signal emitted when the future at index is finished (i.e. returned a result)

cancelledAt(index: int, future: Future)Signal emitted when the future at index was cancelled.

resultReadyAt(index: int, result: Any)Signal emitted with the future’s result when successfully finished.

exceptionReadyAt(index: int, exception: BaseException)Signal emitted with the future’s exception when finished with an exception.

progressChanged(donecount: int, count: int)Signal reporting the current completed count

10.1. Orange.widgets.utils.concurrent 63

Page 68: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

doneAllSignal emitted when all the futures have completed.

setFutures(futures)Set the future instances to watch.

Raise a RuntimeError if futures are already set.

Parameters futures (List[Future]) –

flush()Flush all pending signal emits currently enqueued.

Must only ever be called from the thread this object lives in (QObject.thread()).

wait()Wait for for all the futures to complete and enqueue notifications to this object, but do not emit any signals.

Use flush() to emit all signals after a wait()

class Orange.widgets.utils.concurrent.methodinvoke(obj, method, arg_types=(), *, con-ntype=2)

A thin wrapper for invoking QObject’s method through QMetaObject.invokeMethod.

This can be used to invoke the method across thread boundaries (or even just for scheduling delayed calls withinthe same thread).

Note: An event loop MUST be running in the target QObject’s thread.

Parameters

• obj (QObject) – A QObject instance.

• method (str) – The method name. This method must be registered with the Qt objectmeta system (e.g. decorated by a Slot decorator).

• arg_types (tuple) – A tuple of positional argument types.

• conntype (Qt.ConnectionType) – The connection/call type. Qt.QueuedConnection(the default) and Qt.BlockingConnection are the most interesting.

See also:

QMetaObject.invokeMethod

Example

>>> app = QCoreApplication.instance() or QCoreApplication([])>>> quit = methodinvoke(app, "quit", ())>>> t = threading.Thread(target=quit)>>> t.start()>>> app.exec()0

static from_method(method, arg_types=(), *, conntype=2)Create and return a methodinvoke instance from a bound method.

Parameters

64 Chapter 10. API

Page 69: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

• method (Union[types.MethodType, types.BuiltinMethodType]) – Abound method of a QObject registered with the Qt meta object system (e.g. decoratedby a Slot decorators)

• arg_types (Tuple[Union[type, str]]) – A tuple of positional argument types.

• conntype (Qt.ConnectionType) – The connection/call type(Qt.QueuedConnection and Qt.BlockingConnection are the most interesting)

Returns invoker

Return type methodinvoke

10.1. Orange.widgets.utils.concurrent 65

Page 70: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

66 Chapter 10. API

Page 71: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Python Module Index

oOrange.widgets.utils.concurrent, 61

67

Page 72: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

68 Python Module Index

Page 73: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Index

AappendRadioButton() (in module Or-

ange.widgets.gui), 49assert_domain_equal() (Or-

ange.widgets.tests.base.WidgetTest method),59

attributeIconDict (in module Or-ange.widgets.gui), 53

attributeItem() (in module Orange.widgets.gui),53

Bbrief (Orange.widgets.widget.StateInfo.Summary at-

tribute), 42button() (in module Orange.widgets.gui), 51

Ccallback (Orange.widgets.gui.LineEditWFocusOut at-

tribute), 54cancelled (Orange.widgets.utils.concurrent.FutureWatcher

attribute), 62cancelledAt (Orange.widgets.utils.concurrent.FutureSetWatcher

attribute), 63checkBox() (in module Orange.widgets.gui), 46comboBox() (in module Orange.widgets.gui), 48ControlledList (class in Orange.widgets.gui), 55create_widget() (Or-

ange.widgets.utils.widgetpreview.WidgetPreviewmethod), 59

createAttributePixmap() (in module Or-ange.widgets.gui), 55

customEvent() (Or-ange.widgets.utils.concurrent.FutureWatchermethod), 63

DdataValidityCallback (Or-

ange.widgets.gui.OrangeListBox attribute),54

default_icon() (Or-ange.widgets.widget.StateInfo.Summary classmethod), 43

defaultSizeHint (Or-ange.widgets.gui.OrangeListBox attribute),54

details (Orange.widgets.widget.StateInfo.Summaryattribute), 43

done (Orange.widgets.utils.concurrent.FutureWatcherattribute), 62

doneAll (Orange.widgets.utils.concurrent.FutureSetWatcherattribute), 63

doneAt (Orange.widgets.utils.concurrent.FutureSetWatcherattribute), 63

doubleSpin() (in module Orange.widgets.gui), 50DoubleSpinBoxWFocusOut (class in Or-

ange.widgets.gui), 54dragDropCallback (Or-

ange.widgets.gui.OrangeListBox attribute),54

EenableDragDrop (Or-

ange.widgets.gui.OrangeListBox attribute),54

exception() (Orange.widgets.utils.concurrent.FutureWatchermethod), 62

exceptionReady (Or-ange.widgets.utils.concurrent.FutureWatcherattribute), 62

exceptionReadyAt (Or-ange.widgets.utils.concurrent.FutureSetWatcherattribute), 63

exec_widget() (Or-ange.widgets.utils.widgetpreview.WidgetPreviewmethod), 59

Ffinished (Orange.widgets.utils.concurrent.FutureWatcher

attribute), 62

69

Page 74: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

finishedAt (Orange.widgets.utils.concurrent.FutureSetWatcherattribute), 63

flush() (Orange.widgets.utils.concurrent.FutureSetWatchermethod), 64

focusInCallback (Or-ange.widgets.gui.LineEditWFocusOut at-tribute), 54

format (Orange.widgets.widget.StateInfo.Summary at-tribute), 43

from_method() (Or-ange.widgets.utils.concurrent.methodinvokestatic method), 64

future() (Orange.widgets.utils.concurrent.FutureWatchermethod), 62

FutureSetWatcher (class in Or-ange.widgets.utils.concurrent), 63

FutureWatcher (class in Or-ange.widgets.utils.concurrent), 61

HhSlider() (in module Orange.widgets.gui), 50

Iicon (Orange.widgets.widget.StateInfo.Summary

attribute), 43indentedBox() (in module Orange.widgets.gui), 52Input (class in Orange.widgets.widget), 40input_summary_changed (Or-

ange.widgets.widget.StateInfo attribute),43

Llabel() (in module Orange.widgets.gui), 52lineEdit() (in module Orange.widgets.gui), 47LineEditWFocusOut (class in Orange.widgets.gui),

54listBox() (in module Orange.widgets.gui), 48

Mmaster (Orange.widgets.gui.OrangeListBox attribute),

54Message (class in Orange.widgets.widget), 42methodinvoke (class in Or-

ange.widgets.utils.concurrent), 64miscellanea() (in module Orange.widgets.gui), 55

NNoInput (Orange.widgets.widget.StateInfo attribute),

43NoOutput (Orange.widgets.widget.StateInfo attribute),

43

OogLabels (Orange.widgets.gui.OrangeListBox at-

tribute), 54ogValue (Orange.widgets.gui.OrangeListBox at-

tribute), 54Orange.widgets.utils.concurrent (module),

61OrangeListBox (class in Orange.widgets.gui), 54Output (class in Orange.widgets.widget), 41output_summary_changed (Or-

ange.widgets.widget.StateInfo attribute),43

OWWidget (class in Orange.widgets.widget), 42

PprogressChanged (Or-

ange.widgets.utils.concurrent.FutureSetWatcherattribute), 63

RradioButtonsInBox() (in module Or-

ange.widgets.gui), 48result() (Orange.widgets.utils.concurrent.FutureWatcher

method), 62resultReady (Orange.widgets.utils.concurrent.FutureWatcher

attribute), 62resultReadyAt (Or-

ange.widgets.utils.concurrent.FutureSetWatcherattribute), 63

rubber() (in module Orange.widgets.gui), 53run() (Orange.widgets.utils.widgetpreview.WidgetPreview

method), 58

Ssend_signals() (Or-

ange.widgets.utils.widgetpreview.WidgetPreviewmethod), 59

separator() (in module Orange.widgets.gui), 53setFuture() (Orange.widgets.utils.concurrent.FutureWatcher

method), 62setFutures() (Orange.widgets.utils.concurrent.FutureSetWatcher

method), 64setLayout() (in module Orange.widgets.gui), 55shutdown() (Orange.widgets.utils.concurrent.ThreadExecutor

method), 61spin() (in module Orange.widgets.gui), 49SpinBoxWFocusOut (class in Orange.widgets.gui), 54StateInfo (class in Orange.widgets.widget), 42StateInfo.Empty (class in Orange.widgets.widget),

43StateInfo.Partial (class in Or-

ange.widgets.widget), 43StateInfo.set_input_summary() (in module

Orange.widgets.widget), 43

70 Index

Page 75: Orange Development Documentation · 2020-05-27 · Orange Development Documentation, Release 3 We will start with a very simple example. A widget that will output a single integer

Orange Development Documentation, Release 3

StateInfo.set_output_summary() (in moduleOrange.widgets.widget), 43

StateInfo.Summary (class in Or-ange.widgets.widget), 42

submit() (Orange.widgets.utils.concurrent.ThreadExecutormethod), 61

Ttear_down() (Orange.widgets.utils.widgetpreview.WidgetPreview

method), 59ThreadExecutor (class in Or-

ange.widgets.utils.concurrent), 61toolButton() (in module Orange.widgets.gui), 51

Wwait() (Orange.widgets.utils.concurrent.FutureSetWatcher

method), 64widget (Orange.widgets.utils.widgetpreview.WidgetPreview

attribute), 58widget_cls (Orange.widgets.utils.widgetpreview.WidgetPreview

attribute), 58widgetBox() (in module Orange.widgets.gui), 52widgetLabel() (in module Orange.widgets.gui), 51WidgetPreview (class in Or-

ange.widgets.utils.widgetpreview), 58WidgetTest (class in Orange.widgets.tests.base), 59

Index 71