2

I have a QPlainTextEdit widget, and am trying get the cursor to automatically select the inserted text. My current methodology is to select backwards using QTextCursor.WordLeft because using .insertText() moves the cursor to the end of that word. Thanks!

Edit: Further clarification: I ideally want the inserted text to become highlighted, with the cursor placed at the beginning of that inserted word. As an example: State 1 -> State 2

State 1 shows an input word. Then once the user hits the space-bar, the program inserts a word, highlights it, and places the cursor at the beginning of that inserted word, shown in State 2.

class TextBox(QPlainTextEdit):
    def __init__(self):
        QPlainTextEdit.__init__(self)

        font = QtGui.QFont()
        font.setPointSize(12)
        self.setFont(font)

    def keyPressEvent(self, keyEvent):
        super(TextBox, self).keyPressEvent(keyEvent)

        if keyEvent.key()  == Qt.Key_Return :
            self.clear()

        elif keyEvent.key() == Qt.Key_Space:
            cursor = self.get_cursor()
            cursor.insertText("test")    # The area of concern
            cursor.selectionStart()
            cursor.movePosition(QtGui.QTextCursor.WordLeft, QtGui.QTextCursor.KeepAnchor, 1)
            cursor.selectionEnd()
            # Moving the cursor position doesn't seem to do anything


    def get_cursor(self):
        return self.textCursor()

    def get_cursor_pos(self):
        return self.get_cursor().position()
braedynl
  • 31
  • 7
  • Sorry, but your question is a bit unclear to me. Do you want to *select* the text that has just been inserted, while moving the cursor position to the beginning of the selection? – musicamante Nov 03 '19 at 23:01
  • Oh yeah, sorry if that was unclear. I want it so that every time the user hits the space bar, the program will insert a certain word directly after, with that inserted word highlighted/selected. Ideally I would want the cursor at the beginning of the inserted word, yeah. – braedynl Nov 03 '19 at 23:09
  • I updated my original post to better clarify what I'm asking about in case it's still unclear. – braedynl Nov 03 '19 at 23:27
  • It is like an autocompletion suggestion? – Guimoute Nov 04 '19 at 00:03
  • 1
    @Guimoute Yeah it is. It's for a uni project. I made a Markov Model from scratch and am just trying to create a good way to present it. – braedynl Nov 04 '19 at 01:37

1 Answers1

3

What you're missing is that to apply the cursor position and selection, the cursor has to be set back to the text edit.

class TextBox(QPlainTextEdit):
    # ...

    def keyPressEvent(self, keyEvent):
        super(TextBox, self).keyPressEvent(keyEvent)

        if keyEvent.key()  == Qt.Key_Return :
            self.clear()

        elif keyEvent.key() == Qt.Key_Space:
            cursor = self.textCursor()
            cursor.insertText("test")
            cursor.movePosition(QtGui.QTextCursor.WordLeft, QtGui.QTextCursor.KeepAnchor, 1)
            self.setTextCursor(cursor)

Keep in mind that since you're calling the base class implementation of keyPressEvent, you'll always end up with a space before the "new" text. If, for any reason you want to avoid that, you'll have to ignore that whenever you get the space key.

    def keyPressEvent(self, keyEvent):
        if keyEvent.key()  == Qt.Key_Return :
            self.clear()

        elif keyEvent.key() == Qt.Key_Space:
            cursor = self.textCursor()
            pos = cursor.position()
            cursor.insertText("test")
            cursor.setPosition(pos, QtGui.QTextCursor.KeepAnchor)
            self.setTextCursor(cursor)
            # by returning, the event won't be sent to the default implementation
            return

        super(TextBox, self).keyPressEvent(keyEvent)
musicamante
  • 41,230
  • 6
  • 33
  • 58
  • You're welcome. Anyway, be careful with this kind of editing. If, as @Guimoute asked in a comment to your original question, you're looking for some kind of autocompletion, you should better look into [QCompleter](https://doc.qt.io/qt-5/qcompleter.html); while its implementation might be/look a bit difficult at the beginning (especially for widgets that don't directly support it like Q[Plain]TextEdit), it's usually better to not try to re-invent the wheel. – musicamante Nov 04 '19 at 00:26
  • Oh huh I didn't know that existed. I'll look into it. And yeah what I'm doing is for a uni project. I wrote up a Markov Model from scratch and am just trying to create a way to present it. I did pretty much reinvent the wheel because there are plenty of Markov Model libraries out there, but part of the project requirements is to show you know how to create one of the models we talked about in class, and so the Markov was just the one I was most interested in. – braedynl Nov 04 '19 at 01:45
  • There's nothing wrong with reinventing the wheel while learning something. The problem comes when we're overcomplicating things whenever it's not necessary: if you have to demonstrate that you can write a function that sums a list of integers you probably won't end up writing a function that converts those numbers to their binary values, uses binary operators to make the addition of those values and returns the final value converted to an integer ;-) – musicamante Nov 04 '19 at 02:14