[MAT logo][Prev][Up][Next]

HMI GTK

[screenshot]Preamble

This module is (c) 2001 Juan Carlos Orozco and is distributed under the GPL license.

Introduction

The purpose of this module is to build a GUI (operator screen) to read and write MatPLC points.

The Glade program is used to build the screen.

In a few words, the HMI GTK module works as follows: Glade generates a .glade file (an XML file representing the GUI). HMI GTK module reads and interprets this .glade file and uses a naming convention to connect widgets with the MatPLC points.

Naming of Widgets

The widgets are connected to the MatPLC points by giving them special names. The easiest way to construct these names is using the widgetnamer wizard.

Using widgetnamer

When widgetnamer starts, it will pop up a dialog box. Fill in the details as follows:
pointThe MATPLC point that should be connected to this widget.
widget numberNormally, this will be 0. If you want several widgets showing the same point, you need to number them 0, 1, 2 etc
typeThe type of point to which we are connecting. For coils, this will be bool (on/off), for registers you have to check what type they are and pick appropriately. All the points used by DSP are f32 (floating-point number).
parameter 1This has different meanings depending on the type. For instance, for the bool type this will be the ON text or image.
parameter 2This has different meanings depending on the type. For instance, for the bool type this will be the OFF text or image.
Note that for image names, no extension is required - a .xpm is added automatically.

Once you have filled it in, click the "Select" button (or press Enter in one of the text fields), then use the middle button to paste the name into glade. The entries can be cleared with the "Clear" button, or you can simply edit them to get the next widget name.

Explanation of the widget names

The names are put together as follows:
_pointname[.number[.type][.parameter1[.parameter2]]]

The number field is needed because every widget in a window must have a unique name. type can be bool, i32, i16, i8, u32, u16, u8 or f32. The default type is bool.

Example: _left.0.bool.on.off

This can be the name of a LabelWidget that will be displaying "on" or "off" depending on the state of the point named "left" at the matplc.conf file.

Kinds of widgets

The widgets that are currently supported are:

GtkLabel (Output)
Supports all types.
param1 = on text message.
param2 = off text message.
GtkProgressBar (Output)
Supports f32.
Range is limited by the widget settings.
GnomePixmap (Output)
Supports all types.
param1 = on bitmap filename (.xpm extension is automatically added)
param2 = off bitmap filename (.xpm extension is automatically added)
GtkPlotCanvas (Output)
Supports f32.
Additional information: see below
GtkToggleButton (Input)
Supports bool type.
Add Signal: toggled, Handler: update_value
GtkRadioButton (Input)
Supports bool type.
Add Signal: toggled, Handler: update_value
Set the same Group-ID (eg. radio) to all connected Radio-Button's.
GtkCheckButton (Input)
Supports bool type.
Add Signal: toggled, Handler: update_value
GtkButton (Input)
Supports bool type.
Add signal: pressed, Handler: update_value
Add signal: released, Handler: reset_value
Note: One can make special set or reset buttons by just adding
the pressed or released signal respectively.
GtkEntry (Input)
Supports all types.
Add Signal: activate or changed, Handler: update_value
GtkHScale and GtkVScale (Input)
Supports f32, u32, u16, u8, i32, i16 and i8.
Add Signal: button-release-event, Handler: update_value
GtkSpinButton (Input)
Supports f32, u32, u16, u8, i32, i16 and i8.
Add Signal: changed, Handler: update_value
GtkOptionMenu (Input)
Supports i32.
Add only one dummy-Item to the Itemlist eg. "---".
GtkSocket (External)
Supports u32.
Point gets XID of the socket window.
With this XID you can plug from an external module.

Please take a look to demo/widgets_gtk how to use the widgets.

Odds and ends

In order for input widgets to work one must add a signal with handler = update_value.

In order to be able to write variables, they should be assigned to this module in the matplc.conf file. The default module name for the HMI module is hmi_gtk.

One can place other widgets and they won't interfere with MatPLC as long as their names don't start with an underscore "_".

Putting it all together

The suggested way of building a project is to create a project in glade named hmi_gtk. Then add a Gnome Application Window found on the Gnome palette. Delete unwanted menu options and toolbar options. The about menu option will automatically display this project credits. One can add widgets to this window and connect widgets to the MatPLC by following the previously described naming convention.

Closing main window with delete_event (from window-manager, e.g. X-Button):
The main window (app1) must connect the signal "delete_event" with the quit_handler. The quit_handler (when called by "delete_event") sets the point "quit_app1".
In matplc.conf you have to

  1. create the point "quit_app1"
  2. assign the point "quit_app1" to plcshutdown.

To build a multi window project one can then add normal Window Widgets found on the GTK+ basic palette of Glade. To open this additional windows we need to link a signal from a button, toolbar button or menu option. There are two ways to link windows to widgets (i.e. button):

One way is to use the 10 predefined names for windows, window1 to window10, each one with a predefined Handler function run_window1 to run_window10. When opening a window from a menu option this is the only way to call windows one just need to add the corresponding Handler name to the menu option (i.e. Handler: run_window5). This limits the number of additional windows to call from the menu options to this 10 predefined ones.

There is an alternative way of calling a window that can be used by other Widgets like the button widget. This method uses a common handler called run_window, this handler expects a window name in the Data parameter of the signal. This method does not impose a limit on the number of windows that the project can open. One could also call the predefined windows from this widgets by adding the window handler to the corresponding signal.

Example of connecting a button widget to a window.

Because of performance concerns, there is a feature in the program that only allows one version of each window to be open at one time.

FIXME: How to close windows? ikeya wrote on the mailing list: "... should use delet_event call back."

When saving the project from glade we will get a hmi_gtk.glade file, this file is what the HMI_GTK module uses to run the graphical HMI.

GnomePixmap Widget

With the GnomePixmap-widget you can display pictures in xpm-format according to the value of the associated plc-point.

There are two ways to pass the xpm-file filenames to hmi_gtk.

  1. As param1 and param2 of the widget-name.

    e.g. _abcd.0.bool.on.off

    plc-point = abcd, type = bool
    This will result in the behaviour:
    PLC-Point(s)ValueDisplayed Pixmap
    abcd== 0off.xpm
    abcd > 0on.xpm


  2. Via definitions in matplc.conf under section [hmi_gtk]:

    Widget-name:

    e.g. _abcd.0.i32

    plc-point = abcd, type = i32

    [hmi_gtk]
    GnomePixmap widgetpattern pixmap1 pixmap2 ...
    	
    The widgetpattern can be the name of the widget (without _) or a namepattern with wildcards (similar to filename-match) included (e.g. LED* -> all widgets starting with LED). Note: The last pattern match is used. So the order is important. If you have one widget LEDerrorXYZ and many widgets starting with LED you can do the job like this:
    [hmi_gtk]
    #           widgetpattern   value 0     1      2      3
    GnomePixmap LED*                grey  green  yellow  red
    GnomePixmap LEDerrorXYZ          off  error
    	
    This will result in the behaviour:
    PLC-Point(s)ValueDisplayed Pixmap
    LEDerrorXYZ== 0off.xpm
    LEDerrorXYZ > 0error.xpm
    LED* == 0grey.xpm
    LED* == 1green.xpm
    LED* == 2yellow.xpm
    LED* == 3red.xpm

GtkLabel Widget

With the GtkLabel-widget you can display the value of the associated plc-point.

There are two ways to define the format:

  1. the format is chosen automatically according to the type of the plc-point.

  2. Via definitions in matplc.conf under section [hmi_gtk]:
    [hmi_gtk]
    GtkLabel widgetpattern "format"
    	
    The widgetpattern can be the name of the widget (without _) or a namepattern with wildcards (similar to filename-match) included (e.g. abc* -> all widgets starting with abc). Note: The last pattern match is used. So the order is important. If you have one widget beltSpeed and many widgets ending with Speed you can do the job like this:
    [hmi_gtk]
    #           widgetpattern   format
    GtkLabel  "*Speed"        "%5.2f km/h"
    GtkLabel  beltSpeed       "%7.3f m/s"
    	
    Note:

    If the widgetpattern starts with "*" you have to enclose it in "".

    For valid format-definitions see the printf() documentation.

GtkPlotCanvas Widget

With the GtkPlotCanvas-widget you can draw on an plotting field in two modes.
Example of GtkPlotCanvas

How to create:

  1. Add a new "custom widget".
  2. Widgetname as before with leading underline (e.g. _name)
  3. Creation Function for the "custom widget" is "hmi_GtkPlotCanvas".

Definitions in matplc.conf under section [hmi_gtk]:

[hmi_gtk]
#---------------------------------------------------------------------------------------------
#		- command -	- param 1 -	- param 2 -	- param 3 -	- param 4 -
#---------------------------------------------------------------------------------------------
widgetname	plotctrl	startpoint 	stoppoint       resetpoint
widgetname	channel		y1point		y2point
widgetname	mode		timer/plotxy

# in plotxy-mode required
widgetname	plotx 		xpoint

#[optional] Default-Values see below
widgetname	widget		xsize   	ysize
widgetname	title		title	        x-axis	        y-axis
widgetname	axis		xmin		xmax	        ymin		ymax
widgetname	timer 		scantime

widgetname	color		bg              plot_bg         legend_bg
widgetname	channelcolor	red
widgetname	symboltype	star
widgetname	symbolstyle	opaque
widgetname	symbolsize	2
widgetname 	linestyle	solid
widgetname	linewidth	1
widgetname	pointconnect	straight

Explanation of the commands

[REQUIRED]:

[REQUIRED (plotxy-mode)]:

[OPTIONAL]:

GtkOptionMenu Widget

With the GtkOptionMenu-widget you can choose one item from a list of items.
The Itemlist and the associated points will be defined in the matplc.conf.
Please refer to the demo/widget_gtk example on how to use this widget.

Definitions in matplc.conf:
[plc]
point widgetname "" hmi_gtk i32
point p1         "" hmi_gtk i32
point p2         "" hmi_gtk i32

[hmi_gtk]
widgetname p1 "item1" "item2" ...
widgetname p2 "item11" "item12" ...

widgetname: Name of the widget as defined in "glade" without leading undersore.
p1...pn: Points which will be set by hmi with the corresponding value.

If you select item "item1" p1 will be set to 1, p2 is set to 0.
If you select item "item2" p1 will be set to 2, p2 is set to 0.
If you select item "item11" p2 will be set to 1, p1 is set to 0.
If you select item "item12" p2 will be set to 2, p1 is set to 0.

If the dummy-item (on top of the List) is selected all points are set to 0.

Example:
[plc]
point  menu1    "Menu 1" hmi_gtk i32
point  p1       " " hmi_gtk i32
point  p2       " " hmi_gtk i32

[hmi_gtk]
# widget   point  value: 1        2             3
menu1      p1     "choice1 p1" "choice2 p1"  "choice3 p1"
menu1      p2     "choice1 p2" "choice2 p2"  "choice3 p2"

GtkSocket Widget

Together with GtkPlug, GtkSocket provides the ability to embed widgets from your own module into the hmi_gtk module in a fashion that is transparent to the user.

How to create:

  1. Add a new "custom widget".
  2. Widgetname as before with leading underline (e.g. _name)
  3. Creation Function for the "custom widget" is "hmi_GtkSocket".
The hmi_gtk passes the XID of that widget to the given point.
In your module you have to plug to the GtkSocket with the XID and then you can insert everything you want into the plugged window.
Please refer to the demo/widget_gtk example on how to use this widget.



WARNING:

Due to a bug in glade 0.6.2 and earlier versions, the GnomePixmap scaled state is not saved. This will cause the *.glade configuration file to loose this information each time a change is saved. In this demo the following line was inserted manually for each scaled widget: <scaled>True</scaled>

This simple bug makes working with scaled GnomePixmap images uncomfortable. From glade version 0.6.3 this bug was corrected, this new version could be downloaded from: ftp://ftp.gnome.org/pub/GNOME/stable/sources/glade/glade-0.6.3.tar.bz2 ftp://ftp.gnome.org/pub/GNOME/stable/sources/glade/glade-0.6.3.tar.gz

Libglade does not recognise the scaled state either, therefore an interim solution was implemented in hmi_gtk.c module. The inconvenience is that the name of the pixmap has to be placed on the name of the widget using the following format: .filename.ext_id

The widget is actually scaled to the size of the widget and not using the scale factors of the GnomePixbuf.

[Prev][Up][Next]

$Date: 2005/10/11 13:35:45 $