You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为PyQt5自定义QLabel绘制的点添加提示框(Tooltip)

解决方法

你遇到的错误是因为QPoint只是一个坐标数据类,根本没有setTooltip方法——工具提示(Tooltip)是Qt控件(QWidget及其子类)的功能,不能直接给绘制出来的图形元素绑定。要实现每个点的独立提示,需要自己处理鼠标事件,动态判断鼠标位置并显示对应提示。

修改后的完整代码

from PyQt5.QtWidgets import QApplication, QLabel, QSizePolicy, QToolTip
from PyQt5.QtCore import Qt, QPoint, QEvent
from PyQt5.QtGui import QPixmap, QPainter, QPen

class MyWidget(QLabel):
    def __init__(self):
        super().__init__()
        canvas = QPixmap(1020, 100)
        canvas.fill(Qt.white)
        self.setPixmap(canvas)
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.point_data = []
        # 记录绘制点的半径(pen宽度是15,所以半径取7.5)
        self.point_radius = 7.5

    def paintEvent(self, event):
        painter = QPainter(self)
        pen = QPen(Qt.black, 3)
        painter.setPen(pen)
        painter.drawLine(10, 50, 1000, 50)
        
        pen.setWidth(15)
        painter.setPen(pen)
        for p in self.point_data:
            point = QPoint(p['pos'], 50)
            painter.drawPoint(point)
        painter.end()

    def event(self, event):
        # 处理工具提示事件
        if event.type() == QEvent.ToolTip:
            # 获取当前鼠标在控件内的位置
            mouse_pos = event.pos()
            matched_info = None
            # 遍历所有点,判断鼠标是否在点的范围内
            for p in self.point_data:
                point_x = p['pos']
                point_y = 50
                # 计算鼠标与点的距离,判断是否在点的区域内
                distance_x = abs(mouse_pos.x() - point_x)
                distance_y = abs(mouse_pos.y() - point_y)
                if distance_x <= self.point_radius and distance_y <= self.point_radius:
                    matched_info = p['info_str']
                    break
            if matched_info:
                # 显示对应的提示框
                QToolTip.showText(event.globalPos(), matched_info, self)
            else:
                # 没有匹配的点,隐藏提示框
                QToolTip.hideText()
            return True
        # 其他事件交给父类处理
        return super().event(event)

app = QApplication([])

window = MyWidget()
window.point_data = [
    {'pos': 50,  'info_str': 'hello'},
    {'pos': 200, 'info_str': 'goodbye'}
]
window.show()

app.exec()

关键说明

  1. 移除错误代码:删掉point.setTooltip(p['info_str']),这行代码完全不符合Qt的逻辑。
  2. 记录点的碰撞范围:定义self.point_radius,对应绘制点的实际可交互区域(因为画笔宽度是15,所以半径取7.5)。
  3. 重写event方法处理ToolTip事件:
    • 当触发ToolTip事件时,获取鼠标在控件内的位置。
    • 遍历所有点,判断鼠标是否落在点的范围内(x和y方向的距离都不超过半径)。
    • 如果找到匹配的点,用QToolTip.showText显示对应提示;否则隐藏提示。
  4. 确保父类处理其他事件:最后调用super().event(event)处理非ToolTip类型的事件,保证控件正常工作。

内容的提问来源于stack exchange,提问作者Matteo Salvarezza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:53:19