PyQT5 QTextEdit detects mouse over word when it's not
-
Hi everyone!
I am making a custom text editor and one of the functionalities is to highlight the line and word over which the mouse point is located. It worked perfectly in the sense that when the mouse really is over a word, it detects that word correctly. Here it is working perfectly in an image where my mouse pointer is located on top of the word "fortune":
Here my pointer is below the text in the white area:
And here it is in the small amount of white space above the text, to the right of the topmost sentence:
In other words, the mouse cannot be inside the QTextEdit without being detected as being on top of something and it will default to the closest thing. Why is this happening? I don't think it's a problem in my code. Here is:
def init(self, QTextEdit):
self.setMouseTracking(True)def mouseMoveEvent(self, mouse_event: QMouseEvent) -> None: if self.underMouse(): # get current mouse position position = mouse_event.pos() # create a QTextCursor at that position to select text text_cursor = self.cursorForPosition(position) # extract selected word text_cursor.select(QTextCursor.WordUnderCursor) word_under_cursor = text_cursor.selectedText() text_cursor.removeSelectedText() selected_word_placeholder = '' for char in word_under_cursor: selected_word_placeholder += 'ª' text_cursor.insertText(selected_word_placeholder) # extract selected sentence text_cursor.select(QTextCursor.LineUnderCursor) line_under_cursor = text_cursor.selectedText() text_cursor.removeSelectedText() text_cursor.insertText('SELECTED_SENTENCE_PLACEHOLDER') # replace newlines with a placeholder old_html = self.toHtml() no_newlines_html = old_html.replace('<br/>', 'PL_BR') no_newlines_html = no_newlines_html.replace('<br />', 'PL_BR2') # set the HTML so that we can use the QTextCursor self.setHtml(no_newlines_html) # convert the HTML to text to get rid of previous formatting soup = BeautifulSoup(self.toHtml(), 'lxml') as_text = soup.text # highlight the currently selected line open_highlight_tag = '<span style="background-color: #FFDDDD;">' close_highlight_tag = '</span>' highlighted_text = open_highlight_tag + line_under_cursor + close_highlight_tag bolded_selected_word = '<span style="background-color: #FFFF00;font-weight:bold">' + word_under_cursor + '</span>' # replace the placeholders sentence_placeholder_replaced = as_text.replace('SELECTED_SENTENCE_PLACEHOLDER', highlighted_text) word_placeholder_replaced = sentence_placeholder_replaced.replace(selected_word_placeholder, bolded_selected_word) final_html = word_placeholder_replaced.replace('PL_BR2', '<BR>').replace('PL_BR', '<BR>') # set HTML self.setHtml(final_html)
-
@ZeHgS I see that there is post-processing of the text where the text is modified, so to simplify the problem I ask myself: if this post-processing is eliminated, does the problem persist? You could provide a simplified and executable code of your problem.
Another question I have is that let's say that everything works as expected, that is, that when the cursor is over a word then it is highlighted, and let's say that after I move the cursor to the white space below the text, do you have a logic that clears what highlighted?
-
Hello! Thank you so much for replying!
Yes, the problem was there before the post-processing. The post-processing actually helped me visualize what was going on.
I don't but the issue is that the text gets selected at all when the mouse enters from below, even if it's extremely distant from any text. What else could be causing this? I tried enabling mouse tracking on the parents as well.
-
Hi and welcome to devnet,
I don't have the solution at hand but what about detecting whether you're within the "text zone" and then only apply your logic if that's the case.