Obtain cursor location information in QPlainTextEdit widget

John F Sturtz john at sturtz.org
Mon Mar 22 03:41:15 GMT 2021


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/20210321/385a8151/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.py
Type: text/x-python
Size: 2384 bytes
Desc: not available
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20210321/385a8151/attachment.py>


More information about the PyQt mailing list