-
Notifications
You must be signed in to change notification settings - Fork 3
Class reference
labpype.widget
has the following classes for making new widgets. You can directly import them from labpype.widget
. Alternatively, you can also import them from their own modules.
The documentation has several parts: "Inheritance guide", "APIs", and "Example". "Inheritance guide" lists all the class attributes and instance methods need to be implemented when you subclass Widget
or Dialog
. "APIs" lists all the useful methods you may need when implementing the child classes of Widget
and Dialog
. See "Example" for how to subclass and some usages of the APIs.
-
labpype.widget.widget
-
labpype.widget.dialog
-
labpype.widget.link
-
labpype.widget.field
Widget
is the common base class of all the widgets. In order to create new widget class, you need to specify some class attributes and implement some methods when inherit from the Widget
class.
For convenience, we will use the name Widget
as the class name for all the following class attributes and widget
as the corresponding object name for the methods, while they actually mean the child class that you inherit from Widget
and the object from that child class. For example, we can create a widget class called FirstWidget
whose class attribute FirstWidget.NAME
is "Awesome Widget"
. Here, FirstWidget
is the class you inherit from Widget
and whose class attributes are assigned.
class FirstWidget(Widget):
NAME = "Awesome Widget"
Note that you should never change the values of class attributes of Widget
.
Default: ""
. The default name for the widget displayed on the canvas.
Default: None
. The associated dialog class. The following types of value are accepted:
-
None
- no associated dialog -
DialogClass
- a dialog class -
"V"
or"H"
- for automatic dialog class generation using the specified orientation -
{"ORIENTATION":"V", SIZE:(200,100)}
- a dictionary of class attributes for the dialog class generated automatically
Default: False
. Whether the task should run in a separate thread so that the main canvas is not blocked. The thread should regularly check if it has been stopped using Thread.Checkpoint()
. See the code of the toy example for a detailed usage.
Default: None
. A list values used as keys for accessing and assigning the data of the widget itself. A str
can be used directly as the key. If a data field is used, the key
passed to it is used as the key for the data. A data field provides more flexibility and convenience than a str
. See Data fields. Some examples:
INTERNAL = "DIAMETER"
INTERNAL = "WIDTH", "HEIGHT"
INTERNAL = "WIDTH", FloatField(key="HEIGHT", label="Height")
Default: None
. Create anchors for connections to upstream widgets. It has the following form of value: (aType, key, multiple, pos, name="", anchor=None), (more anchors...)
. The parenthesis can be omitted if there is only one incoming anchor.
-
aType
- anchor type for the anchor. See Anchor types. -
key
- key for accessing the data passed by the upstream widgets connected to this anchor. -
multiple
- does this anchor allow multiple connections? -
pos
- astr
of positions. For example."LT"
indicates this anchor can be positioned to the left or to the top of the widget. -
name
- name for the anchor to be displayed in the status bar when being hovered. -
anchor
- by default (anchor=None
) it uses the base anchor classAnchor
to create an anchor. You can create advanced anchor classes derived fromAnchor
and use them here.
Some examples:
INCOMING = ANCHOR_DNA, "DNA", True, "L", "DNA"
INCOMING = (ANCHOR_DNA, "DNA", True, "L", "DNA"), \
(ANCHOR_ENZYME, "ENZYME", False, "TB", "Enzyme")
Default: None
. Create anchor for connections to downstream widgets. It accepts aType, name="", anchor=None
. The key for outgoing data is always "OUT"
. Therefore, you should never use "OUT"
as the key for incoming or internal data. The position for outgoing anchor is always "RBT"
. Outgoing anchor always support multiple connections.
Default: False
. Whether this widget class is limited to one instance on the canvas.
Default behavior: return Widget.NAME
. The function is called when the state of the widget is changed. You can use the Widget.IsState(state)
method to determine the current state and return the text you want to display on the canvas accordingly.
Default behavior: return JSON formatted str from dumping data
. data
is a dict
containing all the internal and outgoing data. You should override this function if the internal and outgoing data of the widget cannot be dumped by JSON. The purpose of this function is to serialize those data so that it can be loaded later.
Default behavior: return the parsed JSON document. You should override this method according the widget.Save(data)
method. This method is the reverse operation of widget.Save(data)
. f
is a file object opened in binary mode.
Default behavior: none. This method is called when the widget is added to the canvas. It's useful for initializing some internal data.
Default behavior: none. This method is called when the widget is removed from the canvas. It's useful for cleanup the data of the widget.
Default behavior: none. This method is called when the widget leaves "Done"
or "Fail"
state. It's useful for resetting some data between reruns.
Default behavior: return None
. The task that this widget does. The task can be anything. It can run in the main thread as long as it's fast, otherwise it would block the UI. It can run in a thread or a subprocess. It can call and monitor an external tool. You will need to make sure that the task does not change the incoming and internal data, and the outgoing data isn't something like a generator that will be consumed when used. This method should return anything other than None
to indicate the task is successful, and whatever returned will be assigned to the outgoing data of the widget.
See the code in A simple demo. It demonstrates how to run a task in a separate thread or a subprocess. It also shows how to display the progress of the widget on the canvas, as well as how to terminate the thread/subprocess at any time.
Returns True
if state
is the widget's current state. state
is one of the five states: Idle
, Wait
, Work
, Done
, Fail
. You should never call this method in widget.Task()
, as it would create a deadlock if Widget.THREAD=True
.
This method returns True
only if the outgoing anchor is connected.
This method returns True
only if the incoming anchor(s) is connected and is in Done
state.
This method returns True
only if all the internal data are not none
.
Dialog
is the common base class of all the dialogs. You will need to specify some class attributes and implement some methods for the child classes to create new dialogs.
For convenience, we will use the name Dialog
as the class name for all the following class attributes and dialog
as the corresponding object name for the methods, while they actually mean the child class that you inherit from Dialog
and the object from that child class.
Default: True
. Whether the dialog should automatically populate controls based on the data fields in Widget.INTERNAL
.
Default: None
. Specify the size of the dialog. Use a tuple of width and height or a wx.Size
object. Use None
to automatically determine the best smallest size for the dialog.
Default: wx.VERTICAL
. The orientation of the main sizer of the dialog. Use wx.HORIZONTAL
for simple one line dialogs.
Default: 2
. The margin between controls in the dialog.
Default: 80
. The width of the label for the controls.
Default: 20
. The height of one line.
Default behavior: none. When dialogs are created, the following functions are called in order: dialog.Initialize(Sizer)
, automatic addition of controls for the data fields, and dialog.Finalize(Sizer)
. Therefore, put anything here you want to be done before automatic addition of controls.
Default behavior: add standard buttons. See Dialog.AddStdButton(sizer)
. Put anything here you want to be done after automatic addition of controls for the data fields.
Default behavior: none. Tell the dialog how to get data from the widget and set the value of the controls in the dialog.
Default behavior: none. Tell the dialog how to get the value of the controls in the dialog and set the widget's data. If Dialog.AUTO=True
, then you do not need to explicitly set data for the internal data specified by data fields.
Dialog
has many methods for adding UI elements programmatically. They all have the kind of name dialog.AddXXX
. To use them in your dialog.Initialize(Sizer)
and dialog.Finalize(Sizer)
methods, you only need a very basic understanding of how sizing and positioning of controls work in wxPython. Understanding the event system is not necessary. However, if you do, you can make highly interactive dialogs. Further, if you know how to make customized UI controls, you can make the dialog more powerful.
All dialog.AddXXX
methods return the controls added. To get or set the value of the controls, call the corresponding methods (see Example)
dialog.AddXXX
methods have the following common arguments:
-
sizer=wx.Sizer
- The sizer in which controls are added. See Sizers Overview for more details. Note that you do not need to add controls to the sizers manually, asdialog.AddXXX
methods take care of it. -
label=str
- The label for the control to be created.label
s have the widthDialog.LABEL_WIDTH
. -
value=str
- String value of the control. -
width=int
- Width of the control. Use-1
for the control to take all the horizontal space. -
height=int
- Height of the control. Use-1
for the control to take all the vertical space. -
style=long
- A wx style argument to be passed to the control. For example, usestyle=wx.TE_CENTER
forwx.TextCtrl
added usingdialog.AddTextCtrl
to tell the text control to center the text. -
inline=bool
- Whether label and control should be in the same row. IfFalse
, label will appear on top of the control. -
tag=str
- Astr
displayed on the control. -
tags=tuple
- Atuple
ofstr
s from which one is chosen to display on the control according the the control's state. -
choices=tuple
- Atuple
ofstr
s from which selection is made. -
onXXX
- The function called when the control is "XXX"ed. For example,onClick
is called when the control is clicked. All of the following forms of value are valid:onXXX=funcName
onXXX=(funcName, funcArgs...)
onXXX=((funcName1, funcArgs1...), funcName2, (funcName3, funcArgs3...), ...)
-
**kwargs
- Keyword arguments to be passed to the control.
Disable the main canvas. This method is used together with dialog.EnableCanvas()
Enable the main canvas. This method is used together with dialog.DisableCanvas()
Add standard buttons to the dialog. This is the default behavior of dialog.Finalize(Sizer)
. Therefore, you normally wouldn't need to call this method unless you override dialog.Finalize(Sizer)
.
Add a separator.
dialog.AddSectionHead(sizer, tag="")
Add a separator with text.
dialog.AddButton(sizer, label="", tag="", width=80, onClick=None, **kwargs)
Add a button.
dialog.AddButtonToggle(sizer, label="", tags=(), width=80, toggle=False,
onClick=None, **kwargs)
Add a two-state button. toggle=bool
specifies whether this button is toggled.
dialog.AddButtonBundle(sizer, label="", tags=(), width=80, rows=1,
toggled=0, group="", onClick=None, **kwargs)
Add a set of buttons that at any time, only one of them is toggled. toggled=int
is the index of the button toggled. group=str
is the name for this group of buttons. Make sure it's unique in the dialog. rows=int
is the number of rows of buttons.
dialog.AddPickerValue(sizer, label="", choices=(), selected=-1, width=80,
**kwargs)
Add a combo box from which a selection is made. selected=int
is the index of the item selected. -1
indicates no selection.
dialog.AddStaticText(sizer, label="", value="", width=-1)
Add a static text for display purpose only.
dialog.AddLineCtrl(sizer, label="", value="", width=-1, style=0,
onInput=None, hint="", font=None)
Add a text control that does not allow multiple lines. hint=str
is the text displayed when the control has no value. font=str
is a DynaUI
styled argument for the font.
dialog.AddTextCtrl(sizer, label="", value="", width=-1, height=-1, style=0,
inline=True, onInput=None, hint="", font=None)
Add a text control that allows multiple lines. hint=str
is the text displayed when the control has no value. font=str
is a DynaUI
styled argument for the font.
dialog.AddListBox(sizer, label="", choices=(), selected=-1, width=-1,
height=-1, onClick=None, onDClick=None, inline=True)
Add a list box for making a selection. selected=int
is the index of the item selected. -1
indicates no selection.
dialog.AddPickerFile(sizer, label="", value="", width=-1, width2=None, mode="L",
wildcard="All files (*.*)|*.*", hint="", style=0, onSelect=None)
Add a file picker. Use mode="S"
for saving file, or mode="L"
for loading file. Use width2
to change the width of the button for opening the load/save dialog, and width
for the length of the textbox that shows the path.
The following code gives a fully functional dialog that can set the widget data.
class MyWidget(Widget):
NAME = "Dialog Example"
DIALOG = MyDialog
INTERNAL = "BT", "BB", "LC", "TC", "LB", "PV", "PF"
class MyDialog(Dialog):
def Initialize(self, Sizer):
self.AddSectionHead(Sizer, tag="SectionHead", shape="C")
self["BN"] = self.AddButton(Sizer, label="Button", tag="Click me")
self["BT"] = self.AddButtonToggle(Sizer, label="ButtonToggle",
tags=("No", "Yes"))
self["BB"] = self.AddButtonBundle(Sizer, label="ButtonBundle",
tags=list("012345"), rows=2)
self.AddStaticText(Sizer, label="StaticText",
value="Dialog Example")
self["LC"] = self.AddLineCtrl(Sizer, label="LineCtrl")
self["TC"] = self.AddTextCtrl(Sizer, label="TextCtrl")
self["LB"] = self.AddListBox(Sizer, label="ListBox",
choices=list("012345"), selected=3)
self["PV"] = self.AddPickerValue(Sizer, label="PickerValue",
choices=list("012345"), selected=2)
self.AddSeparator(Sizer)
self["PF"] = self.AddPickerFile(Sizer, label="PickerFile")
def SetData(self):
self.Widget["BT"] = self["BT"].IsToggled()
self.Widget["BB"] = self["BB"].GetToggled()
self.Widget["LC"] = self["LC"].GetValue()
self.Widget["TC"] = self["TC"].GetValue()
self.Widget["LB"] = self["LB"].GetStringSelection()
self.Widget["PV"] = self["PV"].GetSelection()
self.Widget["PF"] = self["PF"].GetValue()
def GetData(self):
if self.Widget["BT"] is not None:
self["BT"].SetToggle(self.Widget["BT"])
if self.Widget["BB"] is not None:
self["BB"].SetToggled(self.Widget["BB"])
if self.Widget["LC"] is not None:
self["LC"].SetValue(self.Widget["LC"])
if self.Widget["TC"] is not None:
self["TC"].SetValue(self.Widget["TC"])
if self.Widget["LB"] is not None:
self["LB"].SetStringSelection(self.Widget["LB"])
if self.Widget["PV"] is not None:
self["PV"].SetSelection(self.Widget["PV"])
if self.Widget["PF"] is not None:
self["PF"].SetValue(self.Widget["PF"])
The dialog looks like this:
Anchor types are used for defining legit connections. A widget has one or more anchors, each anchor has an attribute aType
whose value is an anchor type class. For two anchors to be able to connect, their aType
pair should be defined to be legit beforehand.
Anchor types are empty classes used as keys in some dictionary that contains all the legit connections. The reason that a class is chosen as the key over str, int or any other hashable object is that classes are inheritable, and this feature makes it elegant to define legit links. For example, if connections between ANCHOR_STRING
and ANCHOR_SEQUENCE
is defined to be legit, then connections between ANCHOR_STRING
and ANCHOR_DNA
, or ANCHOR_STRING
and ANCHOR_PROTEIN
are also legit automatically, given that ANCHOR_DNA
and ANCHOR_PROTEIN
are subclasses of ANCHOR_SEQUENCE
.
from labpype.widget import ANCHOR_REGULAR
class ANCHOR_SEQUENCE(ANCHOR_REGULAR): pass
class ANCHOR_DNA(ANCHOR_SEQUENCE): pass
class ANCHOR_PROTEIN(ANCHOR_SEQUENCE): pass
The base class for all user-defined anchor types.
The base class for special anchor types (e.g., ANCHOR_ALL
and ANCHOR_NONE
). The connection between two special anchor types is considered not legit.
Anchors whose aType
are ANCHOR_ALL
can connect to any anchors whose aType
are subclasses of ANCHOR_REGULAR
Anchors whose aType
are ANCHOR_NONE
cannot connect to anything.
Instances of data fields are used as value of class attribute Widget.INTERNAL
. They represent the type of input data from the widget's dialog. An argument key
is passed when instantiate a data field. This key
has the same meaning as the string you would use directly for Widget.INTERNAL
. They are used as keys for accessing and assigning data to the widget. Although data field is optional, it has two advantages. First, it validates the value from the dialog, and only assigns the value to the widget if the value is valid. Second, with data fields, it is possible for the Dialog
class to inspect the Widget
for the types of data, and populate the the dialog with appropiate UI controls. Each data field has one or more associated dialog.AddXXX
method used to construct the UI control. See below for the association and Dialog APIs for the associated method.
from labpype.widget.field import *
from labpype.widget import widget
class DataFieldExample(Widget):
NAME = "DataField Example"
DIALOG = "V" # Automatically generate dialog using vertical layout
INTERNAL = \
BooleanField("BOOLEAN", "BooleanField", "No", "Yes"), \
LineField("LINE", "LineField"), \
TextField("TEXT", "TextField"), \
IntegerField("INTEGER", "IntegerField"), \
FloatField("FLOAT", "FloatField"), \
ChoiceField("CHOICE1", "ChoiceField", choices=list("ABC"), widget="C"), \
ChoiceField("CHOICE2", "ChoiceField", choices=list("ABC"), widget="L"), \
ChoiceField("CHOICE3", "ChoiceField", choices=list("ABC"), widget="B"), \
FileField("FILE", "FileField")
The dialog of this widget:
BaseField(key, label, **kwargs)
- The base class of all data fields. You should not directly use this class.
-
key
- the key for accessing and assigning associated data to the widget. -
label
- the label of this field that displays on the dialog. Use""
for no label. -
**kwargs
- keyword arguments to be passed to the associateddialog.AddXXX
method.
BooleanField(key, label, tag1, tag2, **kwargs)
- Associated with
dialog.AddButtonToggle
. - Represent a Boolean value. The value is
True
if the button is toggled, otherwiseFalse
. - No validation.
-
tag1
- text displayed on the button when it is untoggled. -
tag2
- text displayed on the button when it is toggled.
LineField(key, label, maxLength=None, minLength=None, **kwargs)
- Associated with
dialog.AddLineCtrl
. - Represent a single line of text (
str
with no line break). - If
maxLength
orminLength
is notNone
, validate the length accordingly. -
maxLength
- maximum acceptable length of the string. -
minLength
- minimum acceptable length of the string.
TextField(key, label, maxLine=None, minLine=None,
maxLength=None, minLength=None, **kwargs)
- Associated with
dialog.AddTextCtrl
. - Represent a
str
. - If
maxLine
orminLine
is notNone
, validate the number of lines accordingly. - If
maxLength
orminLength
is notNone
, validate the length accordingly. -
maxLine
- maximum acceptable number of lines. -
minLine
- minimum acceptable number of lines. -
maxLength
- maximum acceptable length of the string. -
minLength
- minimum acceptable length of the string.
IntegerField(key, label, maxValue=None, minValue=None, **kwargs)
- Associated with
dialog.AddLineCtrl
. - Represent an
int
. - Validate if the text in the line control can be converted to an
int
. - Then, if
maxValue
orminValue
is not None, validate the value accordingly. -
maxValue
- maximum acceptable value. -
minValue
- minimum acceptable value.
FloatField(key, label, maxValue=None, minValue=None, **kwargs)
- Associated with
dialog.AddLineCtrl
. - Represent a
float
. - Validate if the text in the line control can be converted to a
float
. - Then, if
maxValue
orminValue
is not None, validate the value accordingly. -
maxValue
- maximum acceptable value. -
minValue
- minimum acceptable value.
ChoiceField(key, label, choices=(), widget="C", **kwargs)
- Associated with
dialog.AddPickerValue
by default. - Represent a chosen value from a tuple of
str
s. - Validate that a selection has been made.
-
choices
- a tuple ofstr
s to be selected from. -
widget
- the UI control associated."C"
fordialog.AddPickerValue
,"L"
fordialog.AddListBox
,"B"
fordialog.AddButtonBundle
.
FileField(key, label, **kwargs)
- Associated with
dialog.AddPickerFile
. - Represent a
str
of the path to a file. - No validation.