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.

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).

Example of installing TCL/Tk and tklib
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.

example For example, in Ubuntu:

> sudo apt install tk
> sudo apt install tklib
on Windows 10 64 bit
  1. Download and install Active Tcl (you will be asked to create an account before downloading it).

  2. Download and unzip tklib-0.7.zip. Double-click "installer.tcl" to install the library.

Alternatively:

  1. download tclkit from this page - I use "tclkit-8.5.9-win32-x86_64.zip"

  2. unzip, and rename the executable to "tclkit.exe", placing it somewhere on your PATH

  3. use tclkit in your rstk program by calling start_with("tclkit.exe")

Alternative libraries

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.

Example uses of 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.

  1. every widget has an id field, which gives the Tk identifier.

  2. tell_wish sends a given string directly to wish

  3. 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:

  1. importing the tcl/tk library (using tell_wish)

  2. creating an instance of the underlying Tk widget using a unique id

  3. retaining that id in a struct, for later reference

  4. wrapping the widget’s functions as methods, calling out to Tk with the stored id as a reference.