Important: Please read the Qt Code of Conduct -

WordUnderCursor not working (word being detected when not on top of any words)

  • Hi everyone!
    Why is a word being detected as being under the cursor here? The red arrow in the image starts where the cursor actually is. No matter where I place it, as long as it is inside the window, the program thinks a word is being selected. If the cursor is below the text, it defaults to the very last one. If the cursor is above, it defaults to the first one.

    Thanks a lot!


    from PyQt5.QtWidgets import QTextEdit, QMainWindow, QApplication
    from PyQt5.QtGui import QMouseEvent, QTextCursor
    class Editor(QTextEdit):
        def __init__(self):
            super(Editor, self).__init__()
            # make sure this widget is tracking the mouse position at all times
        def mouseMoveEvent(self, mouse_event: QMouseEvent) -> None:
            if self.underMouse():
                # create a QTextCursor at that position and select text
                text_cursor = self.cursorForPosition(mouse_event.pos())
                word_under_cursor = text_cursor.selectedText()
                # replace substring with placeholder so that repeat occurrences aren't highlighted as well
                selected_word_placeholder = self.replace_selected_text_with_placeholder(text_cursor)
                word_under_cursor = '<span style="background-color: #FFFF00;font-weight:bold;">' + word_under_cursor + '</span>'
                # replace the sentence with the new formatting
                self.setHtml(self.toPlainText().replace(selected_word_placeholder, word_under_cursor))
        def replace_in_html(self, old_string, new_string):
            old_html = self.toHtml()
            new_html = old_html.replace(old_string, new_string)
        # use placeholder so that repeat occurrences of the word are not highlighted
        def replace_selected_text_with_placeholder(self, text_cursor):
            # remove the selected word to be replaced by the placeholder
            # create a placeholder with as many characters as the original word
            word_placeholder = ''
            for char in range(10):
                word_placeholder += '@'
            return word_placeholder
    def set_up(main_window):
        title_editor = Editor()
        title_editor.setText('Venda quente original xiaomi redmi airdots 2 tws fones de ouvido sem fio bluetooth fones controle ai gaming headset come')
    application = QApplication([])
    window = QMainWindow()

  • Lifetime Qt Champion


    Looking at the implementation, I would say it gives you the text cursor "closest" to your mouse position.

  • @SGaist
    The thing the OP may not like is that for the the docs state:

    Selects the word under the cursor. If the cursor is not positioned within a string of selectable characters, no text is selected.

    It's hard to see how "If the cursor is not positioned within a string of selectable characters" comes about for the OP given where he's trying to place it away from any words.

    Given the implementation of cursorForPosition(mouse_event.pos()) I think you would have to look at just where the mouse position is to detect it's not really on any word.

  • Lifetime Qt Champion

    @JonB one problem here is likely the difference between the text cursor and the mouse cursor which can be at different positions at the same time.

  • Thank you both very much for replying! I will implement an extra check, then. Thanks!

Log in to reply