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

