Search code examples
pythonhyperlinkpyqtqlabelpyqt6

How do I change the color of a link temporarily when hovered in a QLabel?


I want the following behavior:

Sample Image

I've tried this, but it makes the link unusable and the color change only occurs if the mouse is in a very specific spot:

from PyQt6.QtWidgets import QLabel, QApplication
from PyQt6.QtGui import QMouseEvent

import sys


class SpecialLinkLabel(QLabel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.linkHovered.connect(self.change_link_color)

    def mouseMoveEvent(self, event: QMouseEvent):
        if 'color: #999999' in self.text():
            self.setText(self.text().replace('color: #999999', 'color: #1597BB'))
        return super().mouseMoveEvent(event)

    def change_link_color(self):
        if 'color: #1597BB' in self.text():
            self.setText(self.text().replace('color: #1597BB', 'color: #999999'))


app = QApplication(sys.argv)
special_label = SpecialLinkLabel(
    'Click <a href="https://random.dog/" style="color: #1597BB">here</a> for something special!</a>'
)
special_label.setOpenExternalLinks(True)
special_label.show()
sys.exit(app.exec())

Not sure if this possible or not.


Solution

  • You already have it. linkHovered passes the URL when it emits you just need to check if it contains any URL or it's just an empty string. If it is not an empty string then change the color else remove it.

    from PyQt5.QtWidgets import QLabel, QApplication
    from PyQt5.QtGui import QMouseEvent, QCursor
    from PyQt5 import QtCore
    
    import sys
    
    class SpecialLinkLabel(QLabel):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.link_text = 'Click <a href="https://google.com" style="color: {color}">here</a> for something special!</a>'
            self.setText(self.link_text)
            self.linkHovered.connect(self.change_link_color)
        
        def change_link_color(self, link):
            print("Hovered: ", repr(link))
            
            self.setText(self.link_text.format(color="red") if link else self.link_text.format(color="blue"))
            
            if link:
                self.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
    
            else:
                self.unsetCursor()
    
    app = QApplication(sys.argv)
    special_label = SpecialLinkLabel()
    special_label.show()
    sys.exit(app.exec())