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

2024-06-09 21:34:15 发布

您现在位置:Python中文网/ 问答频道 /正文

当我将鼠标悬停在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(),但问题是一旦悬停,它就会改变颜色,并且不会重置回原始颜色。注释部分是我尝试过的所有东西


Tags: textselfcomeventhttpstyledefstackoverflow
1条回答
网友
1楼 · 发布于 2024-06-09 21:34:15

它无法正常工作,因为标签居中,而对^{}的调用显然不是:

Returns the rectangle that is covered by ink if character ch were to be drawn at the origin of the coordinate system.

此外,您使用的是更大的字体,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()是因为您以像素为单位设置字体大小,而您最好使用点,因为它们与设备无关(这是字体渲染的首选做法)

相关问题 更多 >