Erlang/Tk (ETK) is an adoption of the Tcl/Tk (4.2) to the Erlang environment. Erlang only uses the Tk part of the Tcl/Tk. This means that the tcl part of the widgets are re-implemented (ported) to Erlang.
Erlang/Tk is an adoption of the Tcl/Tk (4.2) to the Erlang environment. Erlang only uses the Tk part of the Tcl/Tk. This means that the tcl part of the widgets are re-implemented (ported) to Erlang.
Furthermore, in order to be able to effectively use this library, understanding the GUI programming concepts of tcl/tk is absolutely essential. Therefore we recommend a good book on tcl/tk such as "Effective Tcl/Tk Programming" by "Mark Harrisson and Michael McLennan, Addison Wesley 1998" as an introductory text to the "etk" library.
Since Tcl is string based language, the syntax had to be changed somewhat. Instead of writing
<Command> <Path> -option value ..
In erlang we write :
Command Path [{option,value},...]).
This syntax will be more familiar to the erlang programmer. In the same time the binding is straight forward, if you used tcl/tk before it will be a matter of pattern matching to convert an existing Tcl/Tk program into a Erlang/Tk program.
In this first release of etk, the documentation is somewhat poor. The best way to get going with this initial release of etk is to use the widget tour that can be found in the examples directory. The widget tour must be run in the "wtour" directory itself.
% cd etk/examples/wtour % erl Eshell V47.4.1 (abort with ^G) 1> make:all() ...... 2> wtour:start().
To create a widget we use the syntax etk:<widget>(Father, Options)
Options) where options is a list
of {Option,Value}
or Value. This will hopefully become clear as we
introduce some examples.
A script in erlang is a fun. Depending on how and where the fun is bound it must match the correct arity, this is where some understanding of tk is needed. For example, to create a button and bind a function to it that will be executed when the button is pressed we write:
Butt = etk:button(Top, [{text,"My Button"}, {command, fun() -> io:format("Action\n") end}]).
One common thing to do is to let the function send a message to some controlling process such as in:
Self = self(), Butt = etk:button(Top, [{text,"My Button"}, {command, fun() -> Self ! my_button end}]).
The function is evaluated in a different process than then process
that defines the binding, thus the self()
expression must
be evaluated before the binding is created.
If we want to bind a function to the button that is evaluated whenever the mouse enters the button, we have:
tk:bind(Butt, "<Enter>", ['%W'], fun(W) -> io:format("Enter\n") end)
Events are evaluated in the widget context.
When an event, mouse click
etc enters the system, a widget is looked up. Event
functions bound to that
widget are searched for and executed in the order
given by bindtags. The
default binding order is "all class instance".
By returning the atom break
from an event function the evaluation chain is stopped.
Most (if not all) of the etk
api functions
have a corresponding detailed description in the original
tk 4.2 documentation. Whenever appropriate, we provide a
a link to the original documentation.
The module etk
exports an API which is mainly
widget creation where a new widget path is automatically
created, the main API is found in the tk
module.
The etk
module it self can be handy when creating widgets
since it automatically creates a new path which is the
catenation of the parent widget with the type of the new
widget.
For example when we create a new button or frame it is convenient
to not have to explicitly specify the new path to the new widget.
Thus, etk exports a number of function that both generate
a new path as well as create the new widget in a manner similar to:
W = tk:mkpath(Parent,WidgetType), tk:Widget(W, Opts), W.
In particular we have etk
functions to
create the following widgets with a generated widget path.
toplevel
button
canvas
checkbutton
entry
frame
label
listbox
menu
menubutton
message
radiobutton
scale
scrollbar
text
One of the few case where it is necessary to explicitly create the new path to a widget, by hand is when we setup the scrollbar to an other widget. Example:
Top = etk:toplevel([]), tk:wm([title,Top,"Widget tour"]), Self = self(), Text = Top ++ ".txt", ScrollY = Top ++ ".sy", tk:text(Text, [{yscrollcommand, fun(From,To) -> tk:cmd(ScrollY, ["set",From,To]) end}]).