Description
Tcl/Tk has evolved into a practical desktop GUI toolkit due to gaining truly native looking themed widgets on Mac, Windows, and Linux in Tk version 8.5.
Additionally, Ruby 3.0 Ractor (formerly known as Guilds) supports truly parallel multi-threading, making both MRI and Tk finally viable for support in Glimmer (Ruby Desktop Development GUI Library) as an alternative to JRuby on SWT.
The trade-off is that while SWT provides a plethora of high quality reusable widgets for the Enterprise (such as Nebula), Tk enables very fast app startup time and a small memory footprint via MRI Ruby.
Glimmer DSL for Tk alternatives and similar gems
Based on the "GUI" category.
Alternatively, view glimmer-dsl-tk alternatives based on common mentions on social networks and blogs.
-
Glimmer
DSL Framework consisting of a DSL Engine and a Data-Binding Library used in Glimmer DSL for SWT (JRuby Desktop Development GUI Framework), Glimmer DSL for Opal (Pure Ruby Web GUI), Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library), Glimmer DSL for Tk (Ruby Tk Desktop Development GUI Library), Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library), Glimmer DSL for XML (& HTML), and Glimmer DSL for CSS -
Glimmer DSL for LibUI
Glimmer DSL for LibUI - Prerequisite-Free Ruby Desktop Development Cross-Platform Native GUI Library - The Quickest Way From Zero To GUI - If You Liked Shoes, You'll Love Glimmer! - No need to pre-install any prerequisites. Just install the gem and have platform-independent GUI that just works on Mac, Windows, and Linux. -
Glimmer DSL for SWT
Glimmer DSL for SWT (JRuby Desktop Development Cross-Platform Native GUI Framework) - The Quickest Way From Zero To GUI - If You Liked Shoes, You'll Love Glimmer! -
Gladiator (Glimmer Editor)
Gladiator (short for Glimmer Editor) is a Glimmer DSL for SWT sample project under on-going development that demonstrates how to build a text editor in Ruby using Glimmer DSL for SWT (JRuby Desktop Development GUI Library). It is not intended to be a full-fledged editor by any means, yet mostly a fun educational exercise in using Glimmer. Gladiator is also a personal tool for shaping an editor exactly the way I like, with all the keyboard shortcuts I prefer. I leave building truly professional text editors to software tooling experts who would hopefully use Glimmer one day. Otherwise, I have been happily using Gladiator to develop all my open-source projects since May of 2020. -
Glimmer DSL for WX
Glimmer DSL for WX - Ruby Desktop Development GUI Library for the wxWidgets GUI toolkit and wxruby3 binding -
Glimmer DSL for Swing
Glimmer DSL for Swing (JRuby Swing Desktop Development GUI Library) - Enables development of desktop applications using Java Swing and Java 2D, including vector graphics and AWT geometry.
Scout Monitoring - Performance metrics and, now, Logs Management Monitoring with Scout Monitoring
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of Glimmer DSL for Tk or a related project?
README
Glimmer DSL for Tk 0.0.7
MRI Ruby Desktop Development GUI Library
[Contributors Wanted! (Submit a Glimmer App Sample to Get Started)](CONTRIBUTING.md)
Glimmer DSL for Tk enables desktop development with Glimmer in Ruby.
Tcl/Tk has evolved into a practical desktop GUI toolkit due to gaining truly native looking themed widgets on Mac, Windows, and Linux in Tk version 8.5.
Additionally, Ruby 3.0 Ractor (formerly known as Guilds) supports truly parallel multi-threading, making both MRI and Tk finally viable for support in Glimmer (Ruby Desktop Development GUI Library) as an alternative to JRuby on SWT.
The trade-off is that while SWT provides a plethora of high quality reusable widgets for the Enterprise (such as Nebula), Tk enables very fast app startup time and a small memory footprint via MRI Ruby.
Glimmer aims to provide a DSL similar to the Glimmer DSL for SWT to enable more productive desktop development in Ruby with:
- Declarative DSL syntax that visually maps to the GUI widget hierarchy
- Convention over configuration via smart defaults and automation of low-level details
- Requiring the least amount of syntax possible to build GUI
- Bidirectional Data-Binding to declaratively wire and automatically synchronize GUI with Business Models
- Custom Widget support
- Scaffolding for new custom widgets, apps, and gems
- Native-Executable packaging on Mac, Windows, and Linux
Hello, World!
Glimmer code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
root {
label {
text 'Hello, World!'
}
}.open
Run (with the glimmer-dsl-tk gem installed):
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_world.rb'"
Glimmer app:
[glimmer dsl tk screenshot sample hello world](images/glimmer-dsl-tk-screenshot-sample-hello-world.png)
NOTE: Glimmer DSL for Tk is in alpha mode. Please help make better by contributing, adopting for small or low risk projects, and providing feedback. It is still an early alpha, so the more feedback and issues you report the better.
Other Glimmer DSL gems:
- glimmer-dsl-swt: Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)
- glimmer-dsl-opal: Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)
- glimmer-dsl-xml: Glimmer DSL for XML (& HTML)
- glimmer-dsl-css: Glimmer DSL for CSS (Cascading Style Sheets)
Pre-requisites
- Tcl/Tk: Follow the install instructions
- Ruby: On Windows, obtain from the Ruby download page. On the Mac and Linux, it is more convenient to just use RVM and follow the RVM Tk instructions.
For example, on the Mac, you can:
- Install the ActiveTcl Mac package from [ActiveState.com](ActiveState.com)
- Install RVM by running
\curl -sSL https://get.rvm.io | bash -s stable
(and runcurl -sSL https://rvm.io/pkuczynski.asc | gpg --import -
if needed for mentioned security reasons) - Run:
rvm install 2.7.1 --enable-shared --enable-pthread --with-tk --with-tcl
Afterwards, if you open irb
, you should be able to run require 'tk'
successfully.
Setup
Option 1: Install
Run this command to install directly:
gem install glimmer-dsl-tk
Option 2: Bundler
Add the following to Gemfile
:
gem 'glimmer-dsl-tk', '~> 0.0.7'
And, then run:
bundle
Girb (Glimmer IRB)
You can run the girb
command (bin/girb
if you cloned the project locally):
girb
This gives you irb
with the glimmer-dsl-tk
gem loaded and the Glimmer
module mixed into the main object for easy experimentation with GUI.
Tk Concepts
Here is a summary taken from the official Tk Concepts Tutorial
Tk Concepts consist of:
- Widgets: Widgets are all the things that you see onscreen. In our example, we had a button, an entry, a few labels, and a frame. Others are things like checkboxes, tree views, scrollbars, text areas, and so on. Widgets are what are often referred to as "controls"; you'll also often see them referred to as "windows," particularly in Tk's documentation, a holdover from its X11 roots (so under that terminology, both a toplevel window and things like a button would be called windows).
- Geometry Management: If you've been playing around creating widgets, you've probably noticed that just by creating them, they didn't end up showing up onscreen. Having things actually put in the onscreen window, and precisely where in the window they show up is a separate step called geometry management.
- Event Handling: In Tk, as in most other user interface toolkits, there is an event loop which receives events from the operating system. These are things like button presses, keystrokes, mouse movement, window resizing, and so on.
Learn more at the official Tk Concepts Tutorial
Glimmer GUI DSL Concepts
The Glimmer GUI DSL provides a declarative syntax for Tk that:
- Supports smart defaults (e.g. grid layout on most widgets)
- Automates wiring of widgets (e.g. nesting a label under a toplevel root or adding a frame to a notebook)
- Hides lower-level details (e.g. main loop is started automatically when opening a window)
- Nests widgets according to their visual hierarchy
- Requires the minimum amount of syntax needed to describe an app's GUI
The Glimmer GUI DSL follows these simple concepts in mapping from Tk syntax:
- Widget Keyword: Any Tk widget (e.g.
Tk::Tile::Label
) or toplevel window (e.g.TkRoot
) may be declared by its lower-case underscored name without the namespace (e.g.label
orroot
). This is called a keyword and is represented in the Glimmer GUI DSL by a Ruby method behind the scenes. - Args: Any keyword method may optionally take arguments surrounded by parentheses (e.g. a
frame
nested under anotebook
may receive tab options likeframe(text: 'Users')
, which gets used behind the scenes by Tk code such asnotebook.add tab, text: 'Users'
) - Content/Options Block: Any keyword may optionally be followed by a Ruby curly-brace block containing nested widgets (content) and attributes (options). Attributes are simply Tk option keywords followed by arguments and no block (e.g.
title 'Hello, World!'
under aroot
)
Example of an app written in Tk imperative syntax:
root = TkRoot.new
root.title = 'Hello, Tab!'
notebook = ::Tk::Tile::Notebook.new(root).grid
tab1 = ::Tk::Tile::Frame.new(notebook).grid
notebook.add tab1, text: 'English'
label1 = ::Tk::Tile::Label.new(tab1).grid
label1.text = 'Hello, World!'
tab2 = ::Tk::Tile::Frame.new(notebook).grid
notebook.add tab2, text: 'French'
label2 = ::Tk::Tile::Label.new(tab2).grid
label2.text = 'Bonjour, Univers!'
root.mainloop
Example of the same app written in Glimmer declarative syntax:
root {
title 'Hello, Tab!'
notebook {
frame(text: 'English') {
label {
text 'Hello, World!'
}
}
frame(text: 'French') {
label {
text 'Bonjour, Univers!'
}
}
}
}.open
The Grid Geometry Manager
The Grid Geometry Manager is supported via the grid
keyword just as per the Tk documentation, except by nesting under the widget it concerns.
Example:
label {
grid column: 0, row: 2, sticky: 'w'
text 'Year of Birth: '
}
entry {
grid column: 1, row: 2
width 15
text bind(@contact, :year_of_birth)
}
More details can be found in the Hello, Computed! sample below.
Bidirectional Data-Binding
Glimmer supports bidirectional data-binding via the bind
keyword, which takes a model and an attribute.
Combo Data-Binding
Example:
This assumes a Person
model with a country
attribute representing their current country and a country_options
attribute representing available options for the country attribute.
combobox {
state 'readonly'
text bind(person, :country)
}
That code sets the values
of the combobox
to the country_options
property on the person
model (data-binding attribute + "_options" by convention).
It also binds the text
selection of the combobox
to the country
property on the person
model.
It automatically handles all the Tk plumbing behind the scenes, such as using TkVariable
and setting combobox
values
from person.country_options
by convention (attribute_name + "_options").
More details can be found in the Hello, Combo! sample below.
List Single Selection Data-Binding
Tk does not support a native themed listbox, so Glimmer implements its own list
widget on top of Tk::Tile::Treeview
. It is set to single selection via selectmode 'browse'.
Example:
This assumes a Person
model with a country
attribute representing their current country and a country_options
attribute representing available options for the country attribute.
list {
selectmode 'browse'
text bind(person, :country)
}
That code binds the items
text of the list
to the country_options
property on the person
model (data-binding attribute + "_options" by convention).
It also binds the selection
text of the list
to the country
property on the person
model.
It automatically handles all the Tk plumbing behind the scenes.
More details can be found in the Hello, List Single Selection! sample below.
List Multi Selection Data-Binding
Tk does not support a native themed listbox, so Glimmer implements its own list
widget on top of Tk::Tile::Treeview
. It is set to multi selection by default.
Example:
This assumes a Person
model with a provinces
attribute representing their current country and a provinces_options
attribute representing available options for the provinces attribute.
list {
text bind(person, :provinces)
}
That code binds the items
text of the list
to the provinces_options
property on the person
model (data-binding attribute + "_options" by convention).
It also binds the selection
text of the list
to the provinces
property on the person
model.
It automatically handles all the Tk plumbing behind the scenes.
More details can be found in the Hello, List Multi Selection! sample below.
Label Data-Binding
Example:
This assumes a Person
model with a country
attribute.
label {
text bind(person, :country)
}
That code binds the textvariable
value of the label
to the country
property on the person
model.
It automatically handles all the Tk plumbing behind the scenes.
More details can be found in the Hello, Computed! sample below.
Entry Data-Binding
Example:
This assumes a Person
model with a country
attribute.
entry {
text bind(person, :country)
}
That code binds the textvariable
value of the entry
to the country
property on the person
model.
It automatically handles all the Tk plumbing behind the scenes.
More details can be found in the Hello, Computed! sample below.
Command Observer
Buttons can set a command
option to trigger when the user clicks the button. This may be done with the command
keyword, passing in a block directly (no need for proc
as per Tk)
Example:
button {
text "Reset Selection"
command {
person.reset_country
}
}
This resets the person country.
More details can be found in the Hello, Combo! sample below.
Samples
Hello, World!
Glimmer code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
include Glimmer
root {
label {
text 'Hello, World!'
}
}.open
Run (with the glimmer-dsl-tk gem installed):
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_world.rb'"
Glimmer app:
[glimmer dsl tk screenshot sample hello world](images/glimmer-dsl-tk-screenshot-sample-hello-world.png)
Hello, Tab!
Glimmer code (from [samples/hello/hello_tab.rb](samples/hello/hello_tab.rb)):
include Glimmer
root {
title 'Hello, Tab!'
notebook {
frame(text: 'English') {
label {
text 'Hello, World!'
}
}
frame(text: 'French') {
label {
text 'Bonjour, Univers!'
}
}
}
}.open
Run (with the glimmer-dsl-tk gem installed):
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_tab.rb'"
Glimmer app:
[glimmer dsl tk screenshot sample hello tab English](images/glimmer-dsl-tk-screenshot-sample-hello-tab-english.png) [glimmer dsl tk screenshot sample hello tab French](images/glimmer-dsl-tk-screenshot-sample-hello-tab-french.png)
Hello, Combo!
Glimmer code (from [samples/hello/hello_combo.rb](samples/hello/hello_combo.rb)):
# ... more code precedes
root {
title 'Hello, Combo!'
combobox { |proxy|
state 'readonly'
text bind(person, :country)
}
button { |proxy|
text "Reset Selection"
command {
person.reset_country
}
}
}.open
# ... more code follows
Run (with the glimmer-dsl-tk gem installed):
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_combo.rb'"
Glimmer app:
[glimmer dsl tk screenshot sample hello combo](images/glimmer-dsl-tk-screenshot-sample-hello-combo.png) [glimmer dsl tk screenshot sample hello combo dropdown](images/glimmer-dsl-tk-screenshot-sample-hello-combo-dropdown.png)
Hello, List Single Selection!
Glimmer code (from [samples/hello/hello_list_single_selection.rb](samples/hello/hello_list_single_selection.rb)):
# ... more code precedes
root {
title 'Hello, List Single Selection!'
list {
selectmode 'browse'
selection bind(person, :country)
}
button {
text "Reset Selection To Default Value"
command { person.reset_country }
}
}.open
# ... more code follows
Run (with the glimmer-dsl-tk gem installed):
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_list_single_selection.rb'"
Glimmer app:
[glimmer dsl tk screenshot sample hello list single selection](images/glimmer-dsl-tk-screenshot-sample-hello-list-single-selection.png)
Hello, List Multi Selection!
Glimmer code (from [samples/hello/hello_list_multi_selection.rb](samples/hello/hello_list_multi_selection.rb)):
# ... more code precedes
root {
title 'Hello, List Multi Selection!'
list {
selection bind(person, :provinces)
}
button {
text "Reset Selection To Defaults"
command { person.reset_provinces }
}
}.open
# ... more code follows
Run (with the glimmer-dsl-tk gem installed):
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_list_multi_selection.rb'"
Glimmer app:
[glimmer dsl tk screenshot sample hello list multi selection](images/glimmer-dsl-tk-screenshot-sample-hello-list-multi-selection.png)
Hello, Computed!
Glimmer code (from [samples/hello/hello_computed.rb](samples/hello/hello_computed.rb)):
# ... more code precedes
root {
title 'Hello, Computed!'
frame {
grid column: 0, row: 0, padx: 5, pady: 5
label {
grid column: 0, row: 0, sticky: 'w'
text 'First Name: '
}
entry {
grid column: 1, row: 0
width 15
text bind(@contact, :first_name)
}
label {
grid column: 0, row: 1, sticky: 'w'
text 'Last Name: '
}
entry {
grid column: 1, row: 1
width 15
text bind(@contact, :last_name)
}
label {
grid column: 0, row: 2, sticky: 'w'
text 'Year of Birth: '
}
entry {
grid column: 1, row: 2
width 15
text bind(@contact, :year_of_birth)
}
label {
grid column: 0, row: 3, sticky: 'w'
text 'Name: '
}
label {
grid column: 1, row: 3, sticky: 'w'
text bind(@contact, :name, computed_by: [:first_name, :last_name])
}
label {
grid column: 0, row: 4, sticky: 'w'
text 'Age: '
}
label {
grid column: 1, row: 4, sticky: 'w'
text bind(@contact, :age, on_write: :to_i, computed_by: [:year_of_birth])
}
}
}.open
# ... more code follows
Run (with the glimmer-dsl-tk gem installed):
ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_computed.rb'"
Glimmer app:
[glimmer dsl tk screenshot sample hello computed](images/glimmer-dsl-tk-screenshot-sample-hello-computed.png)
Help
Issues
You may submit issues on GitHub.
Click here to submit an issue.
Chat
Process
Planned Features and Feature Suggestions
These features have been planned or suggested. You might see them in a future version of Glimmer DSL for Tk. You are welcome to contribute more feature suggestions.
[TODO.md](TODO.md)
Change Log
[CHANGELOG.md](CHANGELOG.md)
Contributing
[CONTRIBUTING.md](CONTRIBUTING.md)
Contributors
- Andy Maleh (Founder)
Click here to view contributor commits.
License
[MIT](LICENSE.txt)
Copyright (c) 2020-2021 - Andy Maleh.
--
Built for Glimmer (DSL Framework).
*Note that all licence references and agreements mentioned in the Glimmer DSL for Tk README section above
are relevant to that project's source code only.