Obtain cursor location information in QPlainTextEdit widget

John F Sturtz john at sturtz.org
Tue Mar 23 17:23:01 GMT 2021


Hi Maurizio.  Thanks again (you were one of the ones who frequently 
helped me two years ago).

I hit on a solution that is essentially that.  My own statement:

Is it possible to save the widget state information just after every 
keyboard and mouse event, but before the textChangedslot gets called?

at the end of my post got me thinking that way.  As far as I can see, 
the only way the cursor can move (if not programmatically, by the code 
itself) is either by user keyboard input or mouse input.  So putting 
code in to snag the cursor position on each keystroke and mouse button 
release seems to do it.  This picks up the cursor position before it moves.

It seemed like a bit of a sledgehammer solution.  But it seems to work.

Thanks!

/John

> John F Sturtz <mailto:john at sturtz.org>
> Sunday, March 21, 2021 10:41 PM
> Hello PyQt forum.  I posted several questions here a couple years ago, 
> and several people were wonderfully helpful.  I've been away awhile, 
> but am fiddling with another PyQt project, and I seem to be stumped by 
> this.  I feel like I must be stupidly overlooking something.
>
> I have a QPlainTextEdit widget.  I've connected the textChanged signal 
> to a slot.  Now I simply want this:  For the slot to be able to know 
> what the widget looked like -- both text contents and cursor position 
> -- before the change occurred.
>
> First pass idea is to save the state of the widget text and cursor 
> position at the end of the textChanged slot, so the next time around, 
> I have a record of what they previously were.  That works as long as 
> the cursor changes position only because of changing text.
>
> But of course, you can move the cursor without changing text as well.  
> So then I can also connect the cursorPositionChanged signal to a slot, 
> keep track of when the cursor moves, and maintain the previous cursor 
> location that way as well.
>
> The problem is that when text changes, the cursor may also move.  (Not 
> necessarily, but probably).  In which case both slots get called, and 
> by the time the second (textChanged) executes, the information has 
> already been overwritten.
>
> Sample code is attached.  For example, try this:
>
>   * Start up the app.  Widget gets created, pre-populated with text 'abc'.
>   * Move the cursor two positions to the right (between the 'b' and
>     'c').  The cursorPositionChanged slot gets called for both moves,
>     so that at the end, it is aware that the previous cursor position
>     was 1, and the current position is 2.
>   * Now insert a character (either type it or paste it; the result is
>     the same either way).
>
> The cursorPositionChanged slot gets called again, and is briefly aware 
> that the previous cursor location was 2 and it is now 3.  But then it 
> updates the previous position to 3 before exiting (as it must, to be 
> useful).  When the textChanged slot gets called, it no longer has any 
> way to know that the cursor position was 2 prior to the change.
>
> I guess what I need is for the cursorPositionChanged slot to somehow 
> know the difference between when the cursor moved because of changing 
> text and when it just moved.
>
> After much head-scratching, I haven't come up with anything.  But 
> surely there must be a way around this?  (I wish there were a 
> 'textIsAboutToChange' signal ...).  Is it possible to save the widget 
> state information just after every keyboard and mouse event, but 
> before the textChanged slot gets called?
>
> Any thoughts appreciated.
>
> Thanks!
>
> /John

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20210323/30d611bc/attachment.htm>


More information about the PyQt mailing list