我试图改变文本的颜色时,悬停在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()
是因为您以像素为单位设置字体大小,而您应该更好地使用点,因为它们将是独立于设备的(这是字体呈现的首选实践)。