forthebadge forthebadge Gem Version

This gem was last updated on the 30.12.2023 (dd.mm.yyyy notation), at 17:02:22 o'clock.

Create a new root entry:

TITLE = 'This is my widget'
root = TkRoot.new { title TITLE }

Specify width, height, then x-coordinate, then y-coordinate:

root.geometry('800x600+0+0')
root.geometry('250x150+0+0')
root.geometry("500x100") # Just width x height
root.geometry("800x500") # Just width x height
root.geometry("+300+300") # And this will only specify the x and y coordinates

Set the title of the root widget at a later point:

root.title('YO')

Set a minimal size of the root widget:

root.minsize(400, 200)

Make the root window invisible (so that e. g. only the menubar shows up):

root.withdraw

Moving the root-window towards the top-left corner:

root.move(0,0)

Disallow the root window from being resized:

Tk.root.resizable(false, false) # boolean value: (width, height)

Obtain the value of an entry:

use .get

Set the value of an entry:

entry.insert(0, _)

# Note that I was unable to get this to work: entry.configure(text: 'Hey there')

Delete the content of an entry:

entry.delete(0,'end') # Weird that 'end' is used there.

Create an entry (entry tag):

@entry1 = TkEntry.new(outermost_frame, textvariable: @text1) {
  font(MAIN_FONT)
}

Set the width of an entry:

entry.configure(width: 35) # Oddly enough I have no idea what this number stands for. 

Set the background colour of an entry:

background 'steelblue'
root.configure(background: 'black')

Respond to key-events for entry:

entry.bind('Key', proc {|this_key|
  e "This key was pressed: `#{this_key}`"
}, '%K')

Change an entry dynamically:

label = TkLabel.new(top) {
  text  'Hello, World!'
}

TkButton.new(top) {
  text "Cancel"
  command proc {
    label.configure('text'=>"Goodbye, Cruel World!")
  }
  pack('side'=>'right', 'padx'=>10, 'pady'=>10)
}

Now when the Cancel button is pressed, the text in the label will change immediately from Hello, World!'' toGoodbye, Cruel World!''

Creating buttons in Tk and via the tk_paradise gem

Use this Syntax to create a button:

TkButton.new(root, text: entry)
TkButton.new(root, text: 'is').grid("columnspan"=>3, "sticky"=>"ew")
TkButton.new(root, text: 'two').grid("row"=>1, "column"=>3, "columnspan"=>3)

Button is-clicked event (clicked callback):

command proc {
  e 'Hello.'
}

Add the button to the main root:

button.pack

Create a new grid:

TkGrid.grid(buttons[0], buttons[1], buttons[2], columnspan: 2 )

Start the mainloop:

Tk.mainloop
Tk.run # Or this variant when the tk_paradise gem is used.

Specify font size:

root.option_add('*Font', '25')

Return the available fonts:

pp TkFont.names
# ["TkCaptionFont", "TkSmallCaptionFont", "TkTooltipFont",
#  "TkFixedFont", "TkHeadingFont", "TkMenuFont", "TkIconFont",
#  "TkTextFont", "TkDefaultFont"]

1 TkDefaultFont:      The default for all GUI items not otherwise specified.
2 TkTextFont:         Used for entry widgets, listboxes, etc.
3 TkFixedFont:        A standard fixed-width font.
4 TkMenuFont:         The font used for menu items.
5   TkHeadingFont:      The font typically used for column headings in lists and tables.
6 TkCaptionFont:      A font for window and dialog caption bars.
7 TkSmallCaptionFont: A smaller caption font for subwindows or tool dialogs
8 TkIconFont:         A font for icon captions.
9 TkTooltipFont:      A font for tooltips.

Specify a font to use (font tag):

font = TkFont.new(family: 'Helvetica', size: 20, weight: 'bold')
TkLabel.new(root) { text 'Attention!'; font TkCaptionFont }

MONOSPACED_FONT = TkFont.new(family: 'Hack', size: 22, weight: 'bold')

Create a new tk-variable:

text1 = TkVariable.new

Note that TkVariable implements #to_a, which can be used to convert
its value into an Array.

How to create a label (text):

label = TkLabel.new(root)  {
  textvariable
  borderwidth 5
  font use_this_font
  foreground  'red' # The foreground colour to use.
  relief      'groove'
  pack(side: 'right', padx: '50', pady: '50')
}

Draw on a canvas:

canvas = TkCanvas.new(root)

Multiple spanning in a grid:

.grid(row: 1, column: 3, columnspan: 3)

How to let the button perform an action:

button = Button.new(root, text: 'foobar) { command proc { puts 'I am saying '+::Colours.sfancy('hello world')+'!' } }

Padding in tk:

Use padx and pady for a grid. Example:

.grid(row: 1, column: 3, columnspan: 3, padx: 5, pady: 5)

Pack a tk-label:

TkLabel.new(root) { text 'Hello, World!' pack { padx 25; pady 25; side 'left' } }

Make use of a scrollbar (scrollbar tag):

scrollbar = TkScrollbar.new(root).pack(side: :right, fill: :y)

command proc{|idx|
  list.yview *idx
}

Combo box widget:

list = TkListbox.new(frame).pack  
list.insert("end", "/home")
list.insert("end", "/etc/hosts")

# Or alternatively:
n = TkVariable.new
combo_box = TkCombobox.new(
  root,
  width: 30,
  font:  MONOSPACED_FONT,
  textvariable: n
)
combo_box.values(%w(
  aa bb cc dd ee ff gg hh ii jj kk ll mm nn oo pp qq rr ss tt uu
))
combo_box.grid(column: 0, row: 6)

How to select the current value of such a combo-box:

combo_box.current = 3 # This uses the fourth element.

Query / Obtain values:

This is done via the method .cget().

b.cget('text')    # "OK"
b.cget('justify') # "left"
b.cget('border')  # 5

Events in ruby-tk in general need to make use of .bind, in order to tie an event to a widget.

mouse-over event:

image1 = TkPhotoImage.new { file "img1.gif" } b = TkButton.new(@root) { image image1 command proc { doit } } b.bind("Enter") { b.configure(image: image2) } b.bind("Leave") { b.configure(image: image1) }

The configure method (configure tag):

Every widget in tk supports the .configure() method. button.configure(text: "Goodbye, Cruel World!")

Creating images (image tag, img tag):

image = TkPhotoImage.new(file: 'foobar.png', height: 82)

Create some text:

text = TkText.new(root) { width 20; height 5 }.pack(side: :left)

Append onto the text-widget:

text.insert('end', 'Left in canvas')

Create a frame:

frame = TkFrame(root, highlightbackground: "black", highlightthickness: 2, bd: 0)

Add a button to that frame:

button = TkButton(frame, text: 'Submit', fg: 'black', bg: 'yellow', font: (("Times New Roman"),15))

button.pack()

Set the width of a border around a button:

borderwidth 3 borderwidth 5

Set the style of a border:

Possible values include:

flat

Use it like this:

relief 'flat'
relief 'raised'
relief 'sunken'
relief 'groove'
relief 'ridge'

How to use TkMessage:

TkMessage.new(root) {

Start in the top left corner:

root.geometry('250x150+0+0')

How to use an open-file dialog:

Tk.getOpenFile

How to create a spin-button in ruby-tk (also called a spin-box):

TkSpinbox.new(root) { ...Standard Options... ...Widget-specific Options... }

Such as:

TkSpinbox.new(root) { to 250 from 0 increment 5 pack(side: 'left', padx: '50', pady: '50') }

To center it, use:

justify :center

https://tkdocs.com/tutorial/text.html https://www.tutorialspoint.com/ruby/ruby_tk_dialogbox.htm

Contact information and mandatory 2FA (no longer) coming up in 2022 / 2023

If your creative mind has ideas and specific suggestions to make this gem more useful in general, feel free to drop me an email at any time, via:

shevy@inbox.lt

Before that email I used an email account at Google gmail, but in 2021 I decided to slowly abandon gmail, for various reasons. In order to limit the explanation here, allow me to just briefly state that I do not feel as if I want to promote any Google service anymore when the user becomes the end product (such as via data collection by upstream services, including other proxy-services). My feeling is that this is a hugely flawed business model to begin with, and I no longer wish to support this in any way, even if only indirectly so, such as by using services of companies that try to promote this flawed model.

In regards to responding to emails: please keep in mind that responding may take some time, depending on the amount of work I may have at that moment. So it is not that emails are ignored; it is more that I have not (yet) found the time to read and reply. This means there may be a delay of days, weeks and in some instances also months. There is, unfortunately, not much I can do when I need to prioritise my time investment, but I try to consider all feedback as an opportunity to improve my projects nonetheless.

In 2022 rubygems.org decided to make 2FA mandatory for every gem owner eventually:

see https://blog.rubygems.org/2022/06/13/making-packages-more-secure.html

Mandatory 2FA will eventually be extended to all rubygems.org developers and maintainers. As I can not use 2FA, for reasons I will skip explaining here, this means that my projects will eventually be removed, as I no longer have any control over my projects hosted on rubygems.org (because I can not use 2FA).

At that point, I no longer have any control what is done to my projects since whoever is controlling the gems ecosystem took away our control here. I am not sure at which point ruby became corporate-controlled - that was not the case several years ago, so something has changed.

Ruby also only allows 2FA users to participate on the issue tracker these days:

https://bugs.ruby-lang.org/issues/18800

But this has been reverted some months ago, so it is no longer applicable. Suffice to say that I do not think that we should only be allowed to interact on the world wide web when some 'authority' authenticated us, such as via mandatory 2FA, so I hope this won't come back again.

Fighting spam is a noble goal, but when it also means you lock out real human people then this is definitely NOT a good situation to be had.