在PyQt中鼠标悬停在链接上时更改文本颜色



我试图改变文本的颜色时,悬停在QLabel的链接。我无法使用PyQt提供的标签来实现它,所以我试图通过继承QLabel来创建一个自定义标签。

这是我尝试过的代码,但这不能正常工作:


from PyQt5 import QtGui, QtCore, QtWidgets
import sys

class LinkLabel(QtWidgets.QLabel):
def __init__(self, link=""):
super(LinkLabel, self).__init__()
self.setText('<a href="http://stackoverflow.com/" style="color: black; font: 14px; text-decoration: None;">'
'StackOverflow</a>')
self.setFixedSize(100, 50)
# self.linkHovered.connect(lambda : print("Hovered"))
self.linkActivated.connect(self.reDirect)
#self.setMouseTracking(True)
def reDirect(self, linkStr):
QtGui.QDesktopServices.openUrl(QtCore.QUrl(linkStr))
def mouseMoveEvent(self, event):
print(self.fontMetrics().boundingRect("StackOverflow"), event.pos())
if self.fontMetrics().boundingRect("StackOverflow").contains(event.pos()):
print("Hovered")
self.setText('<a href="http://stackoverflow.com/" style="color: blue; font: 14px; text-decoration: None;">'
'StackOverflow</a>')
else:
self.setText('<a href="http://stackoverflow.com/" style="color: black; font: 14px; text-decoration: None;">'
'StackOverflow</a>')
super(LinkLabel, self).mouseMoveEvent(event)
# def enterEvent(self, event):
#     print("YES", self.fontMetrics().boundingRect(self.text()))
#     if self.fontMetrics().boundingRect(self.text()).contains(event.pos()):
#         print("Hovered")
#         self.setText('<a href="http://stackoverflow.com/" style="color: blue; font: 14px;">'
#                   'SignUp</a>')
#         # self.fontMetrics().tightBoundingRect()
#     super(LinkLabel, self).enterEvent(event)
#
# def leaveEvent(self, event):
#     if not self.fontMetrics().boundingRect(self.text()).contains():
#         self.setText('<a href="http://stackoverflow.com/" style="color: black; font: 14px;">'
#                      'SignUp</a>')
#
#     super(LinkLabel, self).leaveEvent(event)

class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.layout().addWidget(LinkLabel())

def main():
app = QtWidgets.QApplication(sys.argv)
win =MainWindow()
win.show()
sys.exit(app.exec_())

if __name__ == '__main__':
main()

我确实尝试过QLabel.linkHovered.connect(),但问题是,一旦悬停,它会改变颜色,不会重置回原来的颜色。注释部分是我尝试过的所有东西。

它不能正常工作,因为标签居中,而你对boundingRect()的调用显然不是:

如果要在坐标系的原点处绘制字符ch,则返回被墨水覆盖的矩形。

此外,你正在使用一个更大的字体,和fontMetrics不能知道任何关于,因为它是基于小部件的font()

解决方案是使用正确的boundingRect()实现和基于您将要使用的字体构造的字体度量:

def checkHover(self, pos=None):
if pos is None:
pos = self.mapFromGlobal(QtGui.QCursor.pos())
font = self.font()
font.setPixelSize(14)
fm = QtGui.QFontMetrics(font)
textRect = fm.boundingRect(self.rect(), self.alignment(), "StackOverflow")
self.setText('''
<a href="{link}" style="color: {color}; font: 14px; text-decoration: None;">
{alias}</a>'''.format(
link='https://stackoverflow.com', 
alias='StackOverflow', 
color='blue' if pos in textRect else 'black', 
))
def enterEvent(self, event):
self.checkHover()
super(LinkLabel, self).enterEvent(event)
def mouseMoveEvent(self, event):
self.checkHover(event.pos())
super(LinkLabel, self).mouseMoveEvent(event)
def leaveEvent(self, event):
self.checkHover()
super(LinkLabel, self).leaveEvent(event)

请注意,我使用setPixelSize()是因为您以像素为单位设置字体大小,而您应该更好地使用点,因为它们将是独立于设备的(这是字体呈现的首选实践)。

最新更新