A Rust binding to the Tk graphics toolkit.
Tk is suitable for creating simple GUI programs or interactive graphical displays. This library supports a large portion of the Tk API, in a generally rust-like style.
-
crate
- https://crates.io/crates/rstk
Requires an installation of tcltk or tclkit, version 8.5 or later (this library uses the ttk widgets), and optionally tklib (to use the chart module).
- on Linux/Mac OS X
-
The tk
wish
program is often already installed, but otherwise both tk and tklib can be obtained using your usual package manager.
For example, in Ubuntu:
> sudo apt install tk > sudo apt install tklib
- on Windows 10 64 bit
-
-
Download and install Active Tcl (you will be asked to create an account before downloading it).
-
Download and unzip tklib-0.7.zip. Double-click "installer.tcl" to install the library.
-
Alternatively:
-
download tclkit from this page - I use "tclkit-8.5.9-win32-x86_64.zip"
-
unzip, and rename the executable to "tclkit.exe", placing it somewhere on your PATH
-
use tclkit in your rstk program by calling
start_with("tclkit.exe")
For other GUI libraries, see areweguiyet - another tk-based library is tk.
1. Documentation
Start with rstk-examples - the linked "tkdocs" tutorial is worth reading if you are new to Tk or GUI programming, but at the least read through and try out the Rust examples.
The api documentation contains detailed information on all parts of the crate, with each Tk-widget type documented separately.
Also see rstk-plotchart for examples of the chart module.
-
crates using rstk
2. Widget lifetimes
The Tk process operates independently of your rust program. All references to
widgets in rust are merely string names used to 'lookup' the widget when
calling out to Tk. As such, widgets will remain live and visible even if a
variable referring to them goes out of scope in your rust code. If you wish to
destroy a widget, use the destroy
method available on all widgets.
Therefore code can be written in separate functions, so long as it is used between calls to "start_wish" and "mainloop":
use rstk::*;
fn setup(root: &impl rstk::TkWidget) {
let hello = rstk::make_label(root);
hello.text("Hello from Rust/Tk");
hello.grid().layout();
}
fn main() {
let root = rstk::start_wish().unwrap();
setup(&root);
rstk::mainloop();
}
3. Low-level API
The main wrapper aims to provide a rust-friendly, type-checked set of structs and methods for using the Tk library.
However, there are many features in Tk and not all of it is likely to be wrapped. If there is a feature missing, it is possible to directly use Tk commands to access it.
-
every widget has an
id
field, which gives the Tk identifier. -
tell_wish
sends a given string directly to wish -
ask_wish
sends a given string directly to wish and returns, as a "String", the response.
For example, label’s takefocus flag is not wrapped. You can nevertheless set it using:
let label = rstk::make_label(&root);
rstk::tell_wish(&format!("{} configure -takefocus 0", &label.id));
Also useful are:
-
cget
- queries any option and returns its current value -
configure
- used to set any option to a value -
winfo
- returns window-related information
4. Extensions
Extensions can be created with the help of next_wid
, which returns a new,
unique ID in Tk format. Writing an extension requires:
-
importing the tcl/tk library (using
tell_wish
) -
creating an instance of the underlying Tk widget using a unique id
-
retaining that id in a struct, for later reference
-
wrapping the widget’s functions as methods, calling out to Tk with the stored id as a reference.