Issue
I am trying to change the colour of the text when hovered over a link in QLabel. I couldn't achieve it using the label provided by PyQt, So I am trying to create a custom label by inheriting QLabel.
Here is the code I have tried, but this doesn't work properly:
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()
I did try QLabel.linkHovered.connect()
but the problem was that once hovered it would change the colour and wouldn't reset back to the original colour. Comment parts are all the things I tried.
Solution
It doesn't work properly because the label is centered, while your call to boundingRect()
obviously isn't:
Returns the rectangle that is covered by ink if character ch were to be drawn at the origin of the coordinate system.
Moreover, you're using a bigger font, and fontMetrics couldn't know anything about that, since it's based on the widget's font()
.
The solution is to use the correct boundingRect() implementation with a constructed font metrics based on the font you're going to use:
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)
Note that I used setPixelSize()
because you set the font size in pixels, while you should better use points instead, as they would be device independent (which is the preferred practice for font rendering).
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.