-
Notifications
You must be signed in to change notification settings - Fork 4
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 of some of the classes has three parts: "Inheritance Guide", "Example", and "APIs". "Inheritance Guide" lists all the class attributes and instance methods need to be implemented when creating a subclass. "Example" shows a simple case. "APIs" lists all the useful methods that you may need when implementing the methods for the subclasses.
-
labpype.widget.widget
-
labpype.widget.dialog
-
labpype.widget.link
-
labpype.widget.field
Widget
is the common base class of all the widgets. You will need to specify some class attributes and implement some methods for the child classes to create new widgets.
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 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 toy example for a detailed usage.
Default: None
. A list of str
s or data fields used as keys for accessing and assign the data of the widget itself. A data field provides more flexibility and convenience than a str
. See Data fields. Some examples:
INTERNAL = "AGE", "NAME", "SEX"
INTERNAL = "YEAR"
INTERNAL = "AGE", LineField(key="NAME", label="Name")
Default: None
. Create anchors for connections to upstream widgets. It has the following form of value: (AnchorType, IsMultiple, Position, Name, AnchorClass), (more anchors...)
. The parenthesis can be omitted if there is only one incoming anchor.
-
AnchorType
- anchor type for the anchor. See Anchor types. -
IsMultiple
- does this anchor allow multiple connections? -
Position
- 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. -
AnchorClass
- by default it uses the base anchor classAnchor
to create an anchor. You can create advanced anchor classes derived fromAnchor
and use them here.
Default: None
. Create anchor for connections to downstream widgets. It accepts AnchorType, Name, AnchorClass
. 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"
.
Default: False
. Whether this widget 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
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 all the data. You should override this function if the internal and outgoing data of the widget can not be dumped by JSON. The purpose of is 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()
method. This method is the reverse operation of widget.Save()
. f
is a file object opened in binary mode.
Default behavior: none.
Default behavior: none.
Default behavior: none.
Default behavior: return False
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
and dialog.Finalize
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 be able to get or set the value of the controls, you would need to 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 be displayed 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 groups of button. Make sure it's unique in the dialog. rows=int
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.AddFilePicker(sizer, label="", value="", width=-1, mode="S",
wildcard="All files (*.*)|*.*", style=0, onSelect=None)
Add a file picker. Use mode="S"
for saving a file, or mode="L"
for loading a file.
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.