1

I've been attempting to force the "insert" mark to move to the start of a field of text irregardless of where the user clicks on that field. While I have found this post, it does not seem to work in my code. The cursor/insert simply stays at the index where I clicked (Nb: the rest of the function works fine). As a last idea I tried "return 'break'" in case some further function was being run that "restored" the cursor location, but that made no difference. I am using Python 3.4 and Tkinter 8+. Thank-you!!

...
n = ttk.Notebook(p)
n1 = Text(n,width=60,height=15);
...
def EnterStatement(e):
    i=n1.index('current').split('.')
    n1.tag_remove('NewStatement', i[0]+'.0', i[0]+'.0 lineend')
    n1.replace(i[0]+'.16', i[0]+'.46', ' '*30,'flex')
    #the following doesn't work... why?!
    n1.mark_set('insert', i[0]+'.16')
...
n1.tag_bind("NewStatement",'<1>', EnterStatement)
Community
  • 1
  • 1
Lugh
  • 107
  • 9

2 Answers2

1

I think you should bind your text to <ButtonRelease-1> event, not <1> or <Button-1>. In this simple test example binding to <Button-1> will not move the mouse cursor. However, if you bind to <ButtonRelease-1> , the mouse cursor will be moved to the beginning with each click.

from tkinter import *


root = Tk()
text = Text(root)
text.insert(INSERT, "Some example text.\n Some second line of example text")

def onclick(event):
    #print(event)
    event.widget.mark_set(INSERT, '1.0')

text.bind('<ButtonRelease-1>', onclick)
#text.bind('<Button-1>', onclick)

text.pack()


root.mainloop()

I guess that the reason, is that Tkinter sets cursor at click position after binding to <Button-1> is executed, which is not the case when binding to <ButtonRelease-1>. Hope this helps.

Marcin
  • 215,873
  • 14
  • 235
  • 294
  • Thank-you; while I _am_ curious as to why "return 'break'" in conjunction with doesn't seem to do the trick, the definitely did. – Lugh Jun 10 '14 at 02:13
0

The problem is that the default behavior is to move the cursor to where the click happened. Your binding doesn't override the default behavior, so your code moves it and then the default moves it again. You can find a deeper explanation for this if you search for "bind tags" and/or "bindtags".

To prevent the default behavior from happening you must return the string "break" from your function, which stops the event from being processed any further:

def EnterStatement(e):
    ...
    #the following doesn't work... why?!
    n1.mark_set('insert', i[0]+'.16')
    return "break"
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I saw your dialogue on this subject on other posts, which has proved very useful to me with respect to overriding the event, and as mentioned in the question this did occur to me on this topic (also as a result of your earlier posts), but for some reason in this case it does not resolve my issue; however, the other post regarding ButtonRelease does. I'm at a loss to explain why one works and the other doesn't, as both seem sensible to me, but after a few tests the behaviour is clear. – Lugh Jun 10 '14 at 02:10