Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/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!

    83c4ef8f-0efc-4634-a41d-f5bb8d06979a-image.png

    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
            self.setMouseTracking(True)
    
        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())
                text_cursor.select(QTextCursor.WordUnderCursor)
    
                word_under_cursor = text_cursor.selectedText()
                print(word_under_cursor)
    
                # 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)
            self.setHtml(new_html)
    
        # 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
            text_cursor.removeSelectedText()
    
            # create a placeholder with as many characters as the original word
            word_placeholder = ''
            for char in range(10):
                word_placeholder += '@'
            text_cursor.insertText(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')
    
        main_window.setCentralWidget(title_editor)
        main_window.show()
    
    
    application = QApplication([])
    window = QMainWindow()
    
    set_up(window)
    
    application.exec()
    
    

  • Lifetime Qt Champion

    Hi,

    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 text_cursor.select(QTextCursor.WordUnderCursor) 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.

    @ZeHgS
    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