This page is deprecated
HAL Widgets
GladeVcp includes a collection of Gtk widgets with attached HAL pins called HAL Widgets, intended to control, display or otherwise interact with the EMC HAL layer.
They are intended to be used with the glade user interface editor.
With proper installation, the HAL Widgets should show up in glade's 'HAL Python' widget group. Many HAL specific fields in the glade 'General' section have an
associated mouse-over tooltip.
HAL signals come in two variants, bits and numbers. Bits are off/on signals.
Numbers can be "float", "s32" or "u32". For more information on HAL data types see the [->] section.
The GladeVcp widgets can either display the value of the signal with an indicator widget, or modify the signal value with a control widget.
Thus there are four classes of GladeVcp widgets that you can connect to a HAL signal. Another class of helper widgets allow you to organize and label your panel.
- Widgets for indicating "bit" signals: HAL_LED
- Widgets for controlling "bit" signals: HAL_Button, HAL_RadioButton?, HAL_CheckButton?, HAL_RadioButton?
- Widgets for indicating "number" signals: HAL_Label, HAL_ProgressBar?, HAL_Bar, HAL_VBar, HAL_Meter
- Widgets for controlling "number" signals: HAL_SpinButton?, HAL_HScale, HAL_VScale
- Helper widgets: HAL_Table, HAL_HBox
- Tool Path preview: HAL_Gremlin
HAL Widgets inherit methods, properties and signals from the underlying Gtk widgets, so it is helpful to consult the Gtk and PyGTK? documentation as well.
Widget and HAL pin naming
Most HAL widgets have a single associated HAL pin with the same name as the widget (glade: General->Name). Exceptions
to this rule currently are the HAL_Spinbutton, which has two pins: a <widgetname>-f (float) and a <widgetname>-s (s32) pin,
and the HAL_ProgressBar?, which has a <widgetname> value input pin, and a <widgetname>.scale input pin.
Setting pin and widget values
As a general rule, if you need to set a HAL output widget's value from Python code, do so by calling the underlying Gtk 'setter' (e.g. set_active(), set_value()) - do not try
to set the associated pin's value by
halcomp[pinname] = value directly because the widget 'will not notice'.
It might be tempting to 'set HAL widget input pins' programmatically. Note this defeats the purpose of an input pin in the first place - it should be linked to, and
react to signals generated by other HAL components. While there is currently no write protection on writing to input pins in HAL Python, this doesnt
make sense. You might use setp pinname value in the associated halfile for testing though.
It is perfectly OK to set an output HAL pin's value with halcomp[pinname] = value provided this HAL pin is not associated with a widget, that is,
has been created by the hal_glib.GPin(halcomp.newpin(<name>,<type>,<direction>) method (see GladeVCProgramming? for an example).
Noticing when something happens in HAL: the hal-pin-changed signal
Event-driven programming means that the UI tells you when "something happens" - through a callback, like when a button was pressed.
The output HAL widgets (those which display a HAL pin's value) like LED, Bar, VBar, Meter etc, support the
hal-pin-changed signal which may cause a callback into your Python code when - well, a HAL pin changes its value. This means there's no more need for permanent polling of HAL pin changes in your code, the widgets do that in the background and let you know. The example in
configs/gladevcp/examples/complex shows how this is handled in Python.
Here is an example how to set a hal-pin-changed signal for a HAL_LED in the glade UI editor:
Buttons
This group of widget is derived from varios Gtk buttons and consists of HAL_Button, HAL_ToggleButton
?,
HAL_RadioButton
? and CheckButton
? widgets. All of them have a single output BIT pin named identical to the widget.
Buttons have no additional properties compared to their base Gtk classes.
- HAL_Button: instantaneous action, does not retain state. Important signal: pressed
- HAL_ToggleButton?, HAL_CheckButton?: retains on/off state. Important signal: toggled
- HAL_RadioButton?: a one-of-many group. Important signal: toggled (per button).
- Important common methods: set_active(), get_active()
- Important properties: label, image
- Hint: Defining radio button groups in glade:
- - decide on default active button
- - in the other button's General->Group select the default active button's name in the 'Choose a Radio Button in this project' dialog.
- See configs/gladevcp/by-widget/radiobutton for a gladevcp application and UI file for working with radio buttons.
Making buttons react to keys
Out of the box, Gtk buttons and its HAL widget counterparts do not react to key press. To do so, define an 'accelerator' associated with the button. See this glade example on how to do it:
upload:collet-accelerator.ui
Scales
HAL_HScale and HAL_VScale are derived from the GtkHScale
? and GtkVScale
? respectively. They have one output FLOAT pin with name equal to widget name. Scales have no additional properties.
- Hint: To make a scale useful in glade, add an 'Adjustment' (General->Adjustment->New or existing adjustment) and edit the adjustment object. It defines the default/min/max/increment
- values. Also, set adjustment 'Page size' and 'Page increment' to zero to avoid warnings.
SpinButton?
HAL SpinButton
? is derived from GtkSpinButton
? and holds two pins:
- {widgetname}-f: out FLOAT pin
- {widgetname}-s: out S32 pin
- Hint: to be useful, Spinbuttons need an adjustment value like scales, see above.
Label
HAL_Label is simple widget based on GtkLabel
? which represents a HAL pin value in a user-defined format.
The pin's HAL type depends on the
label_pin_type property (0:S32, 1:float, 2:U32), see also the tooltip on General->HAL pin type (note this is different from
PyVCP which has three label widgets, one for each type).
The text displayed depends on the text_template property - an Python format string to represent the pin value.
It defaults to `%s` (values are converted by the str() function) but may contain anything legit in a as argument to Pythons format() method
- Example: Distance: %.03f will display the text and the pin value with 3 fractional digits padded with zeros for a FLOAT pin.
Containers: HAL_HBox and HAL_Table
Compared to their Gtk conterparts they have one
input BIT pin which controls if their child widgets are sensitive or not. If the pin is low then
child widgets are inactive which is the default.
- Hint: if you find some part of your gladevcp application is 'greyed out' (insensitive), see wether a container's pin is unset.
LED
The HAL_Led simulates a real indicator LED . It has a single input BIT pin which
controls it's state: ON or OFF. Leds have several properties which
control their look and feel:
- on_color: a String defining ON color of led. May be any valid gtk.gdk.Color name. Not working on Ubuntu 8.04.
- off_color: String defining OFF color of led. May be any valid gtk.gdk.Color name or special value `dark`. `dark` means that OFF color will be set to 0.4 value of ON color. Not working on Ubuntu 8.04.
- pick_color_on, pick_color_off: Colors for ON and OFF states may be represented as #RRRRGGGGBBBB strings. These are ptional properties which have precedence over `on_color` and `off_color`.
- led_size: LED radius (for square - half of LED's side)
- led_shape: LED Shape. Valid values are 0 for round, 1 for oval and 2 for square shapes.
- led_blink_rate: if set and led is ON then it's blinking. Blink frequency is equal to `led_blink_rate` specified in milliseconds.
As an input widget, LED also supports the hal-pin-changed signal. If you want to get a notification in your code when the
LED's HAL pin was changed, then connect this signal to a handler, for example on_led_pin_changed and provide the handler as follows:
def on_led_pin_changed(self,hal_led,data=None):
print "on_led_pin_changed() - HAL pin value:",hal_led.hal_pin.get()
This will be called at any edge of the signal and also during program startup to report the current value.
Example LEDs:
ProgressBar?
This widget might go away. Use the HAL_HBar and HAL_VBar widgets instead.
The HAL_ProgressBar? is derived from gtk.ProgressBar? and has two float HAL input pins:
- <widgetname> - the current value to be displayed
- <widgetname>.scale - the maximum absolute value of input
It has the following properties:
- scale - value scale. set maximum absolute value of input. Same as setting the <widgetname>.scale pin. A float, range from -2**24 to 2**24.
- green_limit - green zone limit lower limit -- PFIXME: please give example value and effect
- yellow_limit - yellow zone limit lower limit
- red_limit - red zone limit lower limit
- text_template - Text template to display the current value of the <widgetname> pin. Python formatting may be used for dict {"value":value}
-- PFIXME: please give example format string with and without 'dict', whatever that means
Example:
ComboBox?
HAL_ComboBox? is derived from gtk.ComboBox?. It enables choice of a value from a dropdown list.
It exports two HAL pins:
- <widgetname>-f: the current value, type FLOAT
- <widgetname>-s: the current value, type S32
It has the following property which can be set in glade:
- column: the column index, type S32, defaults to -1, range from -1..100 .
In default mode this widgets sets the pins to the index of the chosen list entry. So if your widget has three labels, it may only assume values 0,1 and 2.
In column mode (column > -1), the value reported is chosen from the ListStore array as defined in Glade. So typically your widget definition would
have two columns in the ListStore , one with text displayed in the dropdown, and an int or float value to use for that choice.
There's an example in configs/gladevcp/by-widget/combobox/combobox.{py,ui} which uses column mode to pick a float value from the ListStore .
- If you're confused like me about how to edit ComboBox ListStores and CellRenderer , see http://www.youtube.com/watch?v=Z5_F-rW2cL8 .
Bars
HAL Bar and VBar widgets for horizontal and vertical bars representing float
values. They have one input FLOAT hal pin. Both bars have the following properties:
- invert: Swap min and max direction. An inverted HBar grows from right to left, an inverted VBar from top to bottom.
- min, max: Minimum and maximum value of desired range. It is not an error condition if the current value is outside this range.
- zero: Zero point of range. If it's inside of min/max range then the bar will grow from that value and not from the left (or right) side of the widget. Useful to represent values that may be both positive or negative.
- force_width, force_height: Forced width or height of widget. If not set then size will be deduced from packing or from fixed widget size and bar will fill whole area.
- text_template: Like in Label sets text format for min/max/current values. Can be used to turn off value display.
- bg_color: Background (inactive) color of bar.
- z0_color, z1_color, z2_color: Colors of different value zones. Defaults are `green`, `yellow` and `red`. For description of zones see `z*_border` properties.
- z0_border, z1_border: Define up bounds of color zones. By default only one zone is enabled. If you want more then one zone set `z0_border` and `z1_border` to desired values so zone 0 will fill from 0 to first border, zone 1 will fill from first to second border and zone 2 -- from last border to 1. Borders are set as fractions, values from 0 to 1.
Examples:
Meter
HAL Meter is widget like PyVCP meter representing float value. It have one input FLOAT hal pin. Widget has following properties:
- min, max: Minimum and maximum value of desired range. It is not an error condition if the current value is outside this range.
- force_size: Forced diameter of widget. If not set then size will be deduced from packing or from fixed widget size and meter will fill all available space with respect to aspect ratio.
- text_template: Like in Label sets text format for current value. Can be used to turn off value display.
- label: Large label above center of meter.
- sublabel: Small label below center of meter.
- bg_color: Background color of meter.
- z0_color, z1_color, </t>z2_color</tt>: Colors of different value zones. Defaults are `green`, `yellow` and `red`. For description of zones see `z*_border` properties.
- z0_border, z1_border: Define up bounds of color zones. By default only one zone is enabled. If you want more then one zone set `z0_border` and `z1_border` to desired values so zone 0 will fill from min to first border, zone 1 will fill from first to second border and zone 2 -- from last border to max. Borders are set as values in range min-max.
Examples:
Gremlin toolpath preview for .ngc files
Gremlin is a plot preview widget similar to the Axis preview window.
It assumes a running EMC environment like Axis or Touchy. To connect to it, inspects the INI_FILE_NAME environment variable. Gremlin displays the current .ngc file - it does monitor for changes and reloads the ngc file if the filename in Axis/Touchy? changes. If you run it in a gladevcp application when EMC is not running you might get a traceback because
the Gremlin widget cant find EMC status, like the current filename.
Gremlin does not eport any HAL pins. It has the following properties:
- view : may be any of 'x', 'y', 'z', 'p' (perspective) . Defaults to 'z' view.
- enable_dro : boolean; wether to draw a DRO on the plot or not. Defaults to 'True'.
Example:
Animated function diagrams: HAL widgets in a bitmap
For some applications it might be desirable to have background image - like a functional diagram - and position widgets at appropriate places in
that diagram. A good combination is setting a bitmap background image, like from a .png file, making the gladevcp window fixed-size, and use the glade Fixed widget to position widgets on this image.
The code for the below example is available here: http://git.mah.priv.at/gitweb/gladevcp-image.git