0

I need to make my own event handler that includes the standard up/down arrow keys' functionalities in a text widget. However, there are some quirks I have to program around somehow.

You might think you could just add/subtract a line and it would go up/down as expected. Well, that's sort of true. But, if you have the word-wrap on or something, you'll go up further than you expected on wrapped lines. Plus, the arrow key might not go up eveningly as it usually does whether or not the word wrap is on (seeing as it will stay on the same character no matter where that character is).

So, how do I simulate the regular functionality in Tkinter?

Here's why I need to reprogram the up arrow key (down also)—this isn't essential to my question, but because people like to ask and come up with alternative approaches, here you go:

I'm making a text editor, and the natural way it does things in a Tkinter Text widget has a bug that I plan to eliminate. The bug is that if you select text with shift-home or something and then try to select further text with shift-up (or shift-down, or control-shift-left or control-shift-right) then it might select or deselect some inappropriate stuff, depending on how you do it. It should be easy enough to fix control-shift-left and control-shift-right, but I have the positioning problems with shift-up and shift-down. I've already reprogrammed home, end, left, right, shift-left and shift-right for similar reasons (and Tkinter is awesome because you actually can reprogram stuff like this).

I'm using Python 3.4.

I'm thinking maybe getting the x,y coordinates of the insert might be helpful. I didn't see anything for that, though (just the mouse coordinates).

Brōtsyorfuzthrāx
  • 4,387
  • 4
  • 34
  • 56

1 Answers1

1

I'm not entirely sure what the problem is that you are having. Are you aware you can ask the text widget to calculate an index of the previous line or next line, and to either take wrapped lines into account or ignore the wrapping?

From the tk text widget docs on index modifiers:

+ count ?submodifier? lines

Adjust the index forward by count lines, retaining the same character position within the line. If there are fewer than count lines after the line containing the current index, then set the index to refer to the same character position on the last line of the text. Then, if the line is not long enough to contain a character at the indicated character position, adjust the character position to refer to the last character of the line (the newline). Spaces on either side of count are optional. If the display submodifier is given, then each visual display line is counted separately. Otherwise, if any (or no modifier) is given, then each logical line (no matter how many times it is visually wrapped) counts just once. If the relevant lines are not wrapped, then these two methods of counting are equivalent.

You can also use a minus sign to go backwards.

For example:

next_line = the_widget.index("insert +1 display lines")
Community
  • 1
  • 1
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I was aware of`insert+1l` But I didn't know about display lines. Thanks! That looks like what I need for the word wrap. However, it doesn't let me know how to get the character directly above the insert (which may not necessarily be the same character I'm on, due to characters being different widths, unless I'm using a monopspace font). That's an awesome documentation link, by the way. Is there a way to get the x,y of the insert. Since we can get the position of a given x,y then getting the x,y should do it. – Brōtsyorfuzthrāx May 27 '14 at 16:59
  • 1
    @user2962794: you can use the `dlineinfo` or `bbox` method to get the coordinates of a specific index. – Bryan Oakley May 27 '14 at 19:05
  • Whoa. I just noticed that using display lines automatically makes sure it goes up a straight course (whether or not the word wrap is on). Awesome. So, I don't need to find coordinates! – Brōtsyorfuzthrāx Jun 04 '14 at 00:32
  • Actually, I've noticed that just going up display lines doesn't work exactly the same as the natural arrow key function. It gradually veers to the left, while going up and down. – Brōtsyorfuzthrāx Jun 09 '14 at 20:49
  • I'm trying using bbox to get the x,y coordinates and mark_set(INSERT, "@%d,%d" % (self.arrow_x, self.arrow_y)) to set the insert. However, I think this is font-size specific. I wonder how people usually handle this problem. – Brōtsyorfuzthrāx Jun 09 '14 at 20:51