ruby / tk

Tk interface module using tcltklib
Other
118 stars 22 forks source link

Binding standard widget events does not work on text widget #36

Closed AndyObtiva closed 2 years ago

AndyObtiva commented 3 years ago

Hi,

I tried binding '<KeyPress>', '<KeyRelease>', '<Button-1>' on TkText widget, but they did not result in any firing of changes.

text_test.rb Code example:

require 'tk'
require 'tkextlib/tile'

root = TkRoot.new {title "Text Test"}

text = TkText.new(root) {width 40; height 40}.grid(row: 0, column: 0, sticky: 'nsew')

text.bind('<KeyPress>', -> {puts 'KeyPress'})
text.bind('<KeyRelease>', -> {puts 'KeyRelease'})
text.bind('<Button-1>', -> {puts 'Button-1'})

Tk.mainloop

Help or clarification is appreciated.

AndyObtiva commented 3 years ago

OK, I just discovered a workaround:

@text.tag_add('all', '1.0', 'end')
@text.tag_bind('all', 'KeyRelease', ->(e) {pd e})

I add a tag covering the entire range, and then I bind a standard event on the tag.

I am closing this issue as a result.

AndyObtiva commented 2 years ago

I am reopening this because I discovered that similar code (to the original example on top) runs in Python TKinter, like in this version:

from tkinter import *
from tkinter import ttk

root = Tk()

text = Text(root)
text.grid()
text.insert('1.0', "Some giberish\nMore giberish\nNot well spelled giberish")
def print_info(event):
  print('key press')
  print(event)

text.bind('<KeyPress>', print_info)

root.mainloop()

This is a Ruby-only issue then.

AndyObtiva commented 2 years ago

OK, good news! I found the real solution to this issue:

In Ruby, the original code on top becomes:

require 'tk'
require 'tkextlib/tile'

root = TkRoot.new {title "Text Test"}

text = TkText.new(root) {width 40; height 40}.grid(row: 0, column: 0, sticky: 'nsew')

text.bind('KeyPress', -> {puts 'KeyPress'})
text.bind('KeyRelease', -> {puts 'KeyRelease'})
text.bind('Button-1', -> {puts 'Button-1'})

Tk.mainloop

Basically, standard bind events do not need to be surrounded by <> in Ruby (e.g. use 'KeyPress' instead of '<KeyPress>').

This is solved again, and with a real solutions this time (not a workaround).