1. Problem explained
I want to make the mouse shape change from the I
-beam into a pointing hand when hovering over clickable text in a QTextEdit()
widget. Thanks to the following StackOverflow question, I know how to achieve this goal:
Clickable hyperlink in QTextEdit
Unfortunately, the way to change the cursor shape relies on this global function:
QApplication.setOverrideCursor(Qt.PointingHandCursor)
This works, but has unintended consequences when you move the mouse over other widgets. A cleaner way to change the mouse shape would be to use this function:
self.setCursor(Qt.PointingHandCursor)
with self
being the QWidget()
of interest. Unfortunately, this has no effect on a QTextEdit()
widget.
2. Minimalistic example
Consider the following minimalistic self-contained sample code:
import sys
from PyQt5.Qt import QDesktopServices, QUrl, QApplication, QColor, Qt
from PyQt5.QtWidgets import QTextEdit
class MyWidget(QTextEdit):
def __init__(self):
super().__init__()
self.setMouseTracking(True)
return
def mousePressEvent(self, e):
super().mousePressEvent(e)
self.anchor = self.anchorAt(e.pos())
if self.anchor:
self.setCursor(Qt.PointingHandCursor)
# QApplication.setOverrideCursor(Qt.PointingHandCursor)
return
def mouseReleaseEvent(self, e):
super().mouseReleaseEvent(e)
if self.anchor:
QDesktopServices.openUrl(QUrl(self.anchor))
self.setCursor(Qt.ArrowCursor)
# QApplication.setOverrideCursor(Qt.ArrowCursor)
self.anchor = None
return
def mouseMoveEvent(self, e) -> None:
super().mouseMoveEvent(e)
self.anchor = self.anchorAt(e.pos())
if self.anchor:
self.setCursor(Qt.PointingHandCursor)
# QApplication.setOverrideCursor(Qt.PointingHandCursor)
else:
self.setCursor(Qt.ArrowCursor)
# QApplication.setOverrideCursor(Qt.ArrowCursor)
return
if __name__== '__main__':
app = QApplication(sys.argv)
editor = MyWidget()
cursor = editor.textCursor()
fmt = cursor.charFormat()
fmt.setForeground(QColor('blue'))
address = 'http://example.com'
fmt.setAnchor(True)
fmt.setAnchorHref(address)
fmt.setToolTip(address)
cursor.insertText("This is a link", fmt)
editor.show()
app.exec_()
Please tinker around a bit with this sample code. You will notice:
Activate the lines
QApplication.setOverrideCursor(Qt.PointingHandCursor)
and it works.Use the cleaner
self.setCursor(Qt.PointingHandCursor)
(letsetOverrideCursor()
be commented out) and nothing happens.
3. Solution?
Do you know a way to get self.setCursor(Qt.PointingHandCursor)
working properly on a QTextEdit()
widget? Or do you know another approach to achieve the same goal - without using the setOverrideCursor()
function?