悬停在 QLabel 中时如何临时更改链接的颜色?

Posted

技术标签:

【中文标题】悬停在 QLabel 中时如何临时更改链接的颜色?【英文标题】:How do I change the color of a link temporarily when hovered in a QLabel? 【发布时间】:2021-10-11 20:34:24 【问题描述】:

我想要以下行为:

我已经尝试过了,但它会使链接无法使用,并且只有当鼠标位于非常特定的位置时才会发生颜色变化:

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())

不确定这是否可能。

【问题讨论】:

【参考方案1】:

你已经拥有了。 linkHovered 在发出时传递 URL,您只需要检查它是否包含任何 URL 或者它只是一个空字符串。如果它不是空字符串,则更改颜色,否则将其删除。

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())

【讨论】:

这个最大的问题是它不适用于多个链接(特别是如果多个链接具有相同的 url)。 @ekhumoro 只有在所有 URL 都相同的情况下它才会起作用,此外我不确定为什么需要指向同一个 URL 的多个链接。如果它不同,那么一个简单的检查很可能会起作用(例如:if link=='google.com' elif ...)。 拥有多个指向同一个 url 的链接是很常见的。例如,几乎任何类型的文档都可以做到这一点。我还想知道当两个链接彼此相邻时会发生什么 - 命中测试是否足够准确?但无论如何,您当前的代码示例并不是一个现实的通用解决方案。它应该能够突出显示任意链接,并且不需要对类中的文本/url 进行硬编码。看来 Qt 没有内置此功能。 即使QTextBrowser 也无法更轻松地为此实现通用解决方案。很难可靠地确定每个锚点的开始和结束位置,因此可以动态更改字符格式。底层的QTextDocument 似乎并不适合这种事情。 @ekhumoro 这是目前最好的解决方案。是的,即使链接彼此相邻,它也能完美运行。查看here。另一种解决方案可能需要您手动使用鼠标位置来检查它是否在正确的文本下,这可能不像这样可靠。

以上是关于悬停在 QLabel 中时如何临时更改链接的颜色?的主要内容,如果未能解决你的问题,请参考以下文章

在悬停链接上更改引导导航栏的颜色?

仅为链接更改 h1 悬停颜色

如何为 Tailwindcss 全局更改默认、活动和悬停状态的链接颜色?

不希望导航栏链接在单击时更改颜色(悬停效果)

悬停链接并在 SVG 中更改颜色 [重复]

将鼠标悬停在图像上时如何更改 SVG 的颜色?