Rectangle 27 4

If your bindings are on the text widget, and if the focus is not on the text widget, your text widget will never see the keypress. Focus management is built in to Tkinter, so you shouldn't have to do anything.

To answer your specific question, you can use the method focus_get to retrieve the widget that currently has keyboard focus. You can also bind to <FocusIn> and <FocusOut> to be notified when the widget gains or loses focus.

Also, are you aware that the text widget has a built-in undo facility? The New Mexico Tech website has a nice brief overview: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/text-undo-stack.html

Thank you. It works great, I didn't realize that you could even put binds on text widgets.

python - Detect whether or not cursor is in Text widget - Stack Overfl...

python python-3.x tkinter cursor
Rectangle 27 2

The key is to change the backend's cursord lookup. (E.g. for TkAgg, it's matplotlib.backend_tkagg.cursord.) Otherwise, the navigation toolbar will override whatever you manually specify through Tk.

There's an additional wrinkle if you need things to occur "on hover". Because matplotlib doesn't have a hover event, you'll need to connect a callback to all mouse motion and then detect whether you're over the artist in question.

This example is for the TkAgg backed, but it's essentially identical for other backends. The only differences are in the imports and in the way that cursors are specified (e.g. on Qt, you'd want a Qt cursor object instead of something like the string "hand1").

import matplotlib; matplotlib.use('TkAgg')

import matplotlib.pyplot as plt
import matplotlib.backends.backend_tkagg as tkagg

def main():
    fig, ax = plt.subplots()
    text = ax.text(0.5, 0.5, 'TEST', ha='center', va='center', size=25)
    fig.canvas.callbacks.connect('motion_notify_event', OnHover(text))
    plt.show()

class OnHover(object):
    def __init__(self, artist, cursor='hand1'):
        self.artist = artist
        self.cursor = cursor
        self.default_cursor = tkagg.cursord[1]
        self.fig = artist.axes.figure

    def __call__(self, event):
        inside, _ = self.artist.contains(event)
        if inside:
            tkagg.cursord[1] = self.cursor
        else:
            tkagg.cursord[1] = self.default_cursor
        self.fig.canvas.toolbar.set_cursor(1)

main()
matplotlib.figure.Figure
matplotlib
tkinter
figure.canvas.mpl_connect
fig.canvas.callbacks.connect
AttributeError
fig, ax = plt.subplots()
fig = matplotlib.figure.Figure()
<matplotlib.figure.Figure object>
None
fig.canvas
fig
canvas.callbacks.connect

One more question, can I get a label or value that indicates zoom or pan button in toolbar is activated or inactivated? Current bug is that the connection is suppressed when toolbar button is clicked, but mouse cursor remains to be hand over text. One solution I can get is defining label using text.set_label() and checking the label in OnHover to identify whether zoom or pan is activated. If so, set inside to False. But this seems to be verbose. Any suggestion?

Second question is solved by disconneting the 'motion_notify_event' using figure.canvas.mpl_disconnect(cid) when zoom or pan button is activated.

python - Set hand cursor for picking matplotlib text - Stack Overflow

python matplotlib tkinter
Rectangle 27 2

The key is to change the backend's cursord lookup. (E.g. for TkAgg, it's matplotlib.backend_tkagg.cursord.) Otherwise, the navigation toolbar will override whatever you manually specify through Tk.

There's an additional wrinkle if you need things to occur "on hover". Because matplotlib doesn't have a hover event, you'll need to connect a callback to all mouse motion and then detect whether you're over the artist in question.

This example is for the TkAgg backed, but it's essentially identical for other backends. The only differences are in the imports and in the way that cursors are specified (e.g. on Qt, you'd want a Qt cursor object instead of something like the string "hand1").

import matplotlib; matplotlib.use('TkAgg')

import matplotlib.pyplot as plt
import matplotlib.backends.backend_tkagg as tkagg

def main():
    fig, ax = plt.subplots()
    text = ax.text(0.5, 0.5, 'TEST', ha='center', va='center', size=25)
    fig.canvas.callbacks.connect('motion_notify_event', OnHover(text))
    plt.show()

class OnHover(object):
    def __init__(self, artist, cursor='hand1'):
        self.artist = artist
        self.cursor = cursor
        self.default_cursor = tkagg.cursord[1]
        self.fig = artist.axes.figure

    def __call__(self, event):
        inside, _ = self.artist.contains(event)
        if inside:
            tkagg.cursord[1] = self.cursor
        else:
            tkagg.cursord[1] = self.default_cursor
        self.fig.canvas.toolbar.set_cursor(1)

main()
matplotlib.figure.Figure
matplotlib
tkinter
figure.canvas.mpl_connect
fig.canvas.callbacks.connect
AttributeError
fig, ax = plt.subplots()
fig = matplotlib.figure.Figure()
<matplotlib.figure.Figure object>
None
fig.canvas
fig
canvas.callbacks.connect

One more question, can I get a label or value that indicates zoom or pan button in toolbar is activated or inactivated? Current bug is that the connection is suppressed when toolbar button is clicked, but mouse cursor remains to be hand over text. One solution I can get is defining label using text.set_label() and checking the label in OnHover to identify whether zoom or pan is activated. If so, set inside to False. But this seems to be verbose. Any suggestion?

Second question is solved by disconneting the 'motion_notify_event' using figure.canvas.mpl_disconnect(cid) when zoom or pan button is activated.

python - Set hand cursor for picking matplotlib text - Stack Overflow

python matplotlib tkinter
Rectangle 27 0

Option for text cursor color in Tk is -insertbackground.

textWidget.config(insertbackground=...)

python - How to change text cursor color in Tkinter? - Stack Overflow

python text colors cursor tkinter
Rectangle 27 0

If your bindings are on the text widget, and if the focus is not on the text widget, your text widget will never see the keypress. Focus management is built in to Tkinter, so you shouldn't have to do anything.

To answer your specific question, you can use the method focus_get to retrieve the widget that currently has keyboard focus. You can also bind to <FocusIn> and <FocusOut> to be notified when the widget gains or loses focus.

Also, are you aware that the text widget has a built-in undo facility? The New Mexico Tech website has a nice brief overview: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/text-undo-stack.html

Thank you. It works great, I didn't realize that you could even put binds on text widgets.

python - Detect whether or not cursor is in Text widget - Stack Overfl...

python python-3.x tkinter cursor
Rectangle 27 0

The bbox method can be used to get the bounding box of an index. You can use that to get the position relative to the window. You can use the winfo method to get the x/y of the window.

Typically popups appear next to the mouse rather than the insertion point (though typically, right-clicking first sets the insertion point and then displays a menu).

Thanks, I'm using this to make an auto-complete feature. I feel it's a little more natural to have the popup window near the insertion point for this particular case.

python - The Tkinter Text Widget Insertion Cursor - Stack Overflow

python text popup tkinter
Rectangle 27 0

I realize this is an old question, but I just started working with Tkinter yesterday to develop a Hebrew application in Python. Right-to-left (bidi) is not available as part of the framework, but after a bit of Googling and some research, I managed to convincingly fake it through keybindings and forcibly repositioning the cursor. My Entry widget keeps the justification left, so that the Hebrew text is in roughly the same position as some English on the same box, but this approach could be easily modified for a right-justified box. (Or, right-justification might make this simpler). Nonetheless, here's what I did.

Essentially what you're doing here is manually enforcing cursor position using callbacks, character codes, and index constants. Also, you must account for the arrow keys (mine behave as moving in the direction which they point. I've always hated how RTL usually reverses the arrows. This is easily changed, though, if you prefer otherwise.) Backspace and Del, also, have to cause some manual repositioning. Of course, too, if you're keeping track of the cursor manually, you have to update your tracking variable in the event that the user repositions it using the mouse. Below is my code, with the exception that the use of a global here is intended to remove a mite of complexity from the explanation.

# Here, the necessary bindings.  We're going to 
             # have to make modifications on key press, release,
             # and on a completed mouse click.
             entryWidget.bind("<KeyPress>", rtlPress)
             entryWidget.bind("<KeyRelease>", rtlRelease)
             entryWidget.bind("<ButtonRelease>", rtlMouse)

Next, the three callback functions, which do all of our cursor tracking and relocating.

#With the following functions, keep in mind that we only want the cursor to move RIGHT
#(increase in index) in response to a right arrow press or a DEL.  Essentially, we are
#compensating for any movement but these explicit conditions.  Since the indexing of the 
#cursor position is LTR, holding it in its current position 
#while we append more text is 
#tantamount to moving it right.

#On key release, if an arrow key has been invoked, we update our tracking variable to 
#reflect the new cursor position.  If any other key was pressed, we snap the cursor back 
#to where it was prior to the keypress to prevent it from moving right and cause the
#next letter to be appended on the left side of the previous letter.

def rtlRelease(event):
        global hebCursorPos
        if event.keycode==114 or event.keycode==113:
               hebCursorPos=event.widget.index(INSERT)
        else:
               event.widget.icursor(hebCursorPos)
        print(str(event.keycode)+" "+str(hebCursorPos))

#On keypress, we must compensate for the natural LTR behavior of backspace(22) and
#del(119)

def rtlPress(event):
        global hebCursorPos
        #In LTR text entry, a backspace naturally removes the character to the left of
        #the cursor.
        if event.keycode==22:
               length =  len(event.widget.get())
               #In RTL, the right edge is the beginning of the string, so backspace
               #should do nothing.
               #If we're at the right edge of the string, we insert a meaningless
               #character to be deleted so that it appears to the user as if we have 
               #done nothing.
    if hebCursorPos==length:
                       event.widget.insert(hebCursorPos, " ")
               #In order to cause the backspace to delete the character to the right
               #rather than the left of the cursor from the user's perspective, we step 
               #the cursor forward one.  This will cause the backspace to delete the 
               #character to the left of the new cursor position, which will be the
               #character that was to the right of the cursor from the user's 
               #perspective.  If we were at the right end of the line, we insert a space 
               #and delete it milliseconds later.  We do not need to update the cursor's 
               #position, in the tracking variable, because after the character is 
               #deleted, it is back at the index from which it started, counting index
               #from an LTR perspective.
               event.widget.icursor(hebCursorPos+1)
        else:
               #Del is more of the same.  It deletes the character to the right of the
               #cursor, but we want it to delete the character to the right.
               if event.keycode==119:
               #If we're at the left edge of the string, insert a meaningless character
               #for the del to delete, so that from the user's perspective it does 
               #nothing.
                        if hebCursorPos==0:
                               event.widget.insert(hebCursorPos, " ")
                        #Otherwise, we will be stepping the cursor one to the left, so 
                        #that when it deletes the character to its new right, it will be 
                        #deleting the character from what the user thinks is its left.  
                        #Because we are deleting a character from the left of the cursor 
                        #from the user's perspective, there will be fewer characters to 
                        #the left of the cursor once the operation is complete.  As 
                        #cursor positioning is tracked as an LTR index, we must update
                        #our tracking variable.
                        else:
                                hebCursorPos-=1
                #Now, we snap our cursor to the position of our tracking variable.  
                #Either we are preventing it from drifting right due to overlapping 
                #keypresses, or we are repositioning it to maintain the correct index 
                #after a del.
                event.widget.icursor(hebCursorPos)

#Simply put, if the user repositions the cursor with the mouse, track it.
def rtlMouse(event):
         global hebCursorPos
         hebCursorPos=event.widget.index(INSERT)

Hope this helps! Since it is accomplished by forced cursor motion, there is slight visual cursor jitter during typing, but text ordering appears to be correct, and the cursor seems to always indicate the correct position when the user is not mid-keypress. I'm not making any claims of code perfection, though!

This is a horrible hack, and only tackles a fraction of the problems presented by Arabic/Hebrew text rendering.

localization - Python/Tkinter: Using Tkinter for RTL (right-to-left) l...

python localization tkinter right-to-left
Rectangle 27 0

I realize this is an old question, but I just started working with Tkinter yesterday to develop a Hebrew application in Python. Right-to-left (bidi) is not available as part of the framework, but after a bit of Googling and some research, I managed to convincingly fake it through keybindings and forcibly repositioning the cursor. My Entry widget keeps the justification left, so that the Hebrew text is in roughly the same position as some English on the same box, but this approach could be easily modified for a right-justified box. (Or, right-justification might make this simpler). Nonetheless, here's what I did.

Essentially what you're doing here is manually enforcing cursor position using callbacks, character codes, and index constants. Also, you must account for the arrow keys (mine behave as moving in the direction which they point. I've always hated how RTL usually reverses the arrows. This is easily changed, though, if you prefer otherwise.) Backspace and Del, also, have to cause some manual repositioning. Of course, too, if you're keeping track of the cursor manually, you have to update your tracking variable in the event that the user repositions it using the mouse. Below is my code, with the exception that the use of a global here is intended to remove a mite of complexity from the explanation.

# Here, the necessary bindings.  We're going to 
             # have to make modifications on key press, release,
             # and on a completed mouse click.
             entryWidget.bind("<KeyPress>", rtlPress)
             entryWidget.bind("<KeyRelease>", rtlRelease)
             entryWidget.bind("<ButtonRelease>", rtlMouse)

Next, the three callback functions, which do all of our cursor tracking and relocating.

#With the following functions, keep in mind that we only want the cursor to move RIGHT
#(increase in index) in response to a right arrow press or a DEL.  Essentially, we are
#compensating for any movement but these explicit conditions.  Since the indexing of the 
#cursor position is LTR, holding it in its current position 
#while we append more text is 
#tantamount to moving it right.

#On key release, if an arrow key has been invoked, we update our tracking variable to 
#reflect the new cursor position.  If any other key was pressed, we snap the cursor back 
#to where it was prior to the keypress to prevent it from moving right and cause the
#next letter to be appended on the left side of the previous letter.

def rtlRelease(event):
        global hebCursorPos
        if event.keycode==114 or event.keycode==113:
               hebCursorPos=event.widget.index(INSERT)
        else:
               event.widget.icursor(hebCursorPos)
        print(str(event.keycode)+" "+str(hebCursorPos))

#On keypress, we must compensate for the natural LTR behavior of backspace(22) and
#del(119)

def rtlPress(event):
        global hebCursorPos
        #In LTR text entry, a backspace naturally removes the character to the left of
        #the cursor.
        if event.keycode==22:
               length =  len(event.widget.get())
               #In RTL, the right edge is the beginning of the string, so backspace
               #should do nothing.
               #If we're at the right edge of the string, we insert a meaningless
               #character to be deleted so that it appears to the user as if we have 
               #done nothing.
    if hebCursorPos==length:
                       event.widget.insert(hebCursorPos, " ")
               #In order to cause the backspace to delete the character to the right
               #rather than the left of the cursor from the user's perspective, we step 
               #the cursor forward one.  This will cause the backspace to delete the 
               #character to the left of the new cursor position, which will be the
               #character that was to the right of the cursor from the user's 
               #perspective.  If we were at the right end of the line, we insert a space 
               #and delete it milliseconds later.  We do not need to update the cursor's 
               #position, in the tracking variable, because after the character is 
               #deleted, it is back at the index from which it started, counting index
               #from an LTR perspective.
               event.widget.icursor(hebCursorPos+1)
        else:
               #Del is more of the same.  It deletes the character to the right of the
               #cursor, but we want it to delete the character to the right.
               if event.keycode==119:
               #If we're at the left edge of the string, insert a meaningless character
               #for the del to delete, so that from the user's perspective it does 
               #nothing.
                        if hebCursorPos==0:
                               event.widget.insert(hebCursorPos, " ")
                        #Otherwise, we will be stepping the cursor one to the left, so 
                        #that when it deletes the character to its new right, it will be 
                        #deleting the character from what the user thinks is its left.  
                        #Because we are deleting a character from the left of the cursor 
                        #from the user's perspective, there will be fewer characters to 
                        #the left of the cursor once the operation is complete.  As 
                        #cursor positioning is tracked as an LTR index, we must update
                        #our tracking variable.
                        else:
                                hebCursorPos-=1
                #Now, we snap our cursor to the position of our tracking variable.  
                #Either we are preventing it from drifting right due to overlapping 
                #keypresses, or we are repositioning it to maintain the correct index 
                #after a del.
                event.widget.icursor(hebCursorPos)

#Simply put, if the user repositions the cursor with the mouse, track it.
def rtlMouse(event):
         global hebCursorPos
         hebCursorPos=event.widget.index(INSERT)

Hope this helps! Since it is accomplished by forced cursor motion, there is slight visual cursor jitter during typing, but text ordering appears to be correct, and the cursor seems to always indicate the correct position when the user is not mid-keypress. I'm not making any claims of code perfection, though!

This is a horrible hack, and only tackles a fraction of the problems presented by Arabic/Hebrew text rendering.

localization - Python/Tkinter: Using Tkinter for RTL (right-to-left) l...

python localization tkinter right-to-left
Rectangle 27 0

The key is to change the backend's cursord lookup. (E.g. for TkAgg, it's matplotlib.backend_tkagg.cursord.) Otherwise, the navigation toolbar will override whatever you manually specify through Tk.

There's an additional wrinkle if you need things to occur "on hover". Because matplotlib doesn't have a hover event, you'll need to connect a callback to all mouse motion and then detect whether you're over the artist in question.

This example is for the TkAgg backed, but it's essentially identical for other backends. The only differences are in the imports and in the way that cursors are specified (e.g. on Qt, you'd want a Qt cursor object instead of something like the string "hand1").

import matplotlib; matplotlib.use('TkAgg')

import matplotlib.pyplot as plt
import matplotlib.backends.backend_tkagg as tkagg

def main():
    fig, ax = plt.subplots()
    text = ax.text(0.5, 0.5, 'TEST', ha='center', va='center', size=25)
    fig.canvas.callbacks.connect('motion_notify_event', OnHover(text))
    plt.show()

class OnHover(object):
    def __init__(self, artist, cursor='hand1'):
        self.artist = artist
        self.cursor = cursor
        self.default_cursor = tkagg.cursord[1]
        self.fig = artist.axes.figure

    def __call__(self, event):
        inside, _ = self.artist.contains(event)
        if inside:
            tkagg.cursord[1] = self.cursor
        else:
            tkagg.cursord[1] = self.default_cursor
        self.fig.canvas.toolbar.set_cursor(1)

main()
matplotlib.figure.Figure
matplotlib
tkinter
figure.canvas.mpl_connect
fig.canvas.callbacks.connect
AttributeError
fig, ax = plt.subplots()
fig = matplotlib.figure.Figure()
<matplotlib.figure.Figure object>
None
fig.canvas
fig
canvas.callbacks.connect

One more question, can I get a label or value that indicates zoom or pan button in toolbar is activated or inactivated? Current bug is that the connection is suppressed when toolbar button is clicked, but mouse cursor remains to be hand over text. One solution I can get is defining label using text.set_label() and checking the label in OnHover to identify whether zoom or pan is activated. If so, set inside to False. But this seems to be verbose. Any suggestion?

Second question is solved by disconneting the 'motion_notify_event' using figure.canvas.mpl_disconnect(cid) when zoom or pan button is activated.

python - Set hand cursor for picking matplotlib text - Stack Overflow

python matplotlib tkinter
Rectangle 27 0

This happens because your custom binding fire before the built-in bindings, and it is the built-in bindings that actually modify the widget and change the cursor position.

You can change the order by leveraging bindtags. For more information see this question: Basic query regarding bindtags in tkinter

If you don't want to deal with bindtags, you can bind to <KeyRelease>. Built-in bindings happen on a key press, so the release binding will always fire after the widget has been updated.

python 3.x - Why Text cursor coordinates are not updated correctly? - ...

python-3.x text tkinter
Rectangle 27 0

You can change the insertbackground option of the text widget to whatever you want. share|improve this answer answered Jan 11 '13 at 18:39 Bryan Oakley86.4k986177

Works fine now, thank you very much! Both of you

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

python - How to change text cursor color in Tkinter? - Stack Overflow

python text colors cursor tkinter
Rectangle 27 0

I finally figured out what was going on and has nothing to do with Tkinter, but all Toolkits. I can now honestly say that I can add something to Best Programming Practices and :

Do Not Process Key Events by Binding to a Key Release Method, Instead Process Keys with a Key Press Method

It's not really a programming issue, it's a hardware issue. When a key is pressed, the physical key goes down. There is a spring that pushes the key back up. If that spring or anything about your keyboard causes a key to be even 200ths of second slower, typing even 60 words a minute may cause keys that were typed in one order to come back in another order. This may happen because a spring may be slightly thicker, stiffer, over used, or even sticky mocha cause more resistance.

Capitalization can be affected as well. Pressing the shift key and another key to get an upper case must be simultaneously pressed down. But if you process keys on key release, it is possible the shift key springs up faster than the character key you are capitalizing, which will result in a lower case. This also allows characters to be inverted. If you check on positions of a character when it's typed, you can get the wrong position due to this as well.

Stick with Key Press.

Python - How To Get Cursor Position in Tkinter Text Widget - Stack Ove...

python python-2.7 tkinter
Rectangle 27 0

As usual with Tkinter, there are a number of ways to do this, but one is the easiest: Text.see:

text.insert(END, "spam\n")
text.see(END)

If you want to make sure the start of the new text is visible, not the end of it, or if you only want to do this if the end was already visible beforehand or if the text is active, etc., you may need to look at the other options: scan_mark/scan_dragto, or yview and friends.

Tried this just now and it doesn't seem to have any affect - I'm inserting in the same was as your post suggests, but the .see(END) method doesn't change the viewpoint

@AlexBlundell: Can you show your code? Also, what platform are you on? I tried it with a plain Text and with one hooked up to a Scrollbar, on OS X 10.8 and an old Fedora box, and they both scrolled the viewport, but that doesn't guarantee that it'll work with all code and on all platforms, the way Tk is

@AlexBlundell: this definitely is the solution. If calling see doesn't work for you, you're doing something wrong. Please show us a small program that illustrates your problem so we can see what you're doing.

I was calling the function from the wrong place - this does indeed work :)

Python Tkinter Text Area set cursor to end - Stack Overflow

python tkinter
Rectangle 27 0

This has to do with the order that tkinter processes events. The short answer is, custom bindings on widgets are processed before the default bindings, and it's the default bindings that cause the text to be inserted or deleted, the index changed, etc.

Python tkinter Text INSERT CURRENT Cursor - Stack Overflow

python python-3.x insert tkinter cursor
Rectangle 27 0

This happens because your custom binding fire before the built-in bindings, and it is the built-in bindings that actually modify the widget and change the cursor position.

You can change the order by leveraging bindtags. For more information see this question: Basic query regarding bindtags in tkinter

If you don't want to deal with bindtags, you can bind to <KeyRelease>. Built-in bindings happen on a key press, so the release binding will always fire after the widget has been updated.

python 3.x - Why Text cursor coordinates are not updated correctly? - ...

python-3.x text tkinter
Rectangle 27 0

You can use KeyRelease which is raised after the text change.

text.bind('<KeyRelease-Down>', tipKeyDown)

BTW, CURRENT is corresponds to the character closest to the mouse pointer. (not related to insertion cursor)

Thanks very much, this does work. I have one more question, does mouse have this kind of issue? I mean whether I need to bind the event after left click is released. If it is, what is the keyword for the bind first parameter?

@xuanzhui, I didn't experiment with mouse click. But there are ButtonPress and ButtonRelease like KeyPress and KeyRelease.

Python tkinter Text INSERT CURRENT Cursor - Stack Overflow

python python-3.x insert tkinter cursor
Rectangle 27 0

So, maybe I just made too much work for myself and there's a really simple way to do this that I haven't found, but here's the solution I made to handle this, in case anyone else needs to do the same type of thing:

from Tkinter import Tk, Text
from tkFont import Font


class BlockyCursorText(Text):

    def __init__(self, parent):
        Text.__init__(self, parent, bg='black', fg='green', insertwidth=0,
                      font=Font(family='Courier', size=10))

        # initialize the cursor position and the color of the cursor
        self.cursor = '1.0'
        self.switch = 'green'

        self._blink_cursor()
        self._place_cursor()


    def _place_cursor(self):
        '''check the position of the cursor against the last known position
        every 15ms and update the cursorblock tag as needed'''

        current_index = self.index('insert')

        if self.cursor != current_index:  # if the insertcursor moved
            self.cursor = current_index   # store the new index
            self.tag_delete('cursorblock')# delete the cursorblock tag

            start = self.index('insert')  # get the start
            end = self.index('insert+1c') # and stop indices

            if start[0] != end[0]:         # this handles an index that
                self.insert(start, ' ')    # reaches the end of the line
                end = self.index('insert') # by inserting a space

            self.tag_add('cursorblock', start, end) # add the tag back in
            self.mark_set('insert', self.cursor)    # move the insertcursor

        self.after(15, self._place_cursor)

    def _blink_cursor(self):
        '''alternate the background color of the cursorblock tagged text
        every 600 milliseconds'''

        if self.switch == 'green':
            self.switch = 'black'
        else:
            self.switch = 'green'

        self.tag_config('cursorblock', background=self.switch)

        self.after(600, self._blink_cursor)

if __name__ == '__main__':

    root = Tk()

    text = BlockyCursorText(root)
    text.pack()
    text.insert('1.0', 'hello world')

    root.mainloop()

python - Is there an easy way to make a blocky insert cursor for the T...

python tkinter
Rectangle 27 0

I finally figured out what was going on and has nothing to do with Tkinter, but all Toolkits. I can now honestly say that I can add something to Best Programming Practices and :

Do Not Process Key Events by Binding to a Key Release Method, Instead Process Keys with a Key Press Method

It's not really a programming issue, it's a hardware issue. When a key is pressed, the physical key goes down. There is a spring that pushes the key back up. If that spring or anything about your keyboard causes a key to be even 200ths of second slower, typing even 60 words a minute may cause keys that were typed in one order to come back in another order. This may happen because a spring may be slightly thicker, stiffer, over used, or even sticky mocha cause more resistance.

Capitalization can be affected as well. Pressing the shift key and another key to get an upper case must be simultaneously pressed down. But if you process keys on key release, it is possible the shift key springs up faster than the character key you are capitalizing, which will result in a lower case. This also allows characters to be inverted. If you check on positions of a character when it's typed, you can get the wrong position due to this as well.

Stick with Key Press.

Python - How To Get Cursor Position in Tkinter Text Widget - Stack Ove...

python python-2.7 tkinter