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

PyQt技术问题:点击按钮时QToolTip定位错误如何修正?

QToolTip点击Button1时显示在Button2位置的原因及修复方案

问题描述

点击「Button1」时,QToolTip并未如预期显示在「Button1」上方,而是出现在「Button2」的位置。相关代码如下:

t.py

import logging
import sys
# from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import (
    QApplication, QMainWindow, QPushButton, QToolTip, QVBoxLayout, QWidget
)

class MainWindow(QMainWindow):
    def __init__(self, app: QApplication):
        super().__init__()
        self.app = app
        self.resize(330, 200)
        self.setWindowTitle("Testing")
        layout = QVBoxLayout()
        button1 = QPushButton("Button1")
        layout.addWidget(button1)
        def button1_clicked() -> None:
            self.button_clicked(button1, "Button1")
        button1.clicked.connect(button1_clicked)
        button2 = QPushButton("Button2")
        layout.addWidget(button2)
        def button2_clicked() -> None:
            self.button_clicked(button2, "Button2")
        button2.clicked.connect(button2_clicked)
        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

    def button_clicked(self, button: QPushButton, txt: str) -> None:
        point = button.mapToGlobal(button.pos())
        size = button.size()
        logging.info(f"{txt} pos: {point}")
        logging.info(f"{txt} size: {size}")
        QToolTip.showText(point, txt, msecShowTime=4000)

def main():
    logging.basicConfig(level=logging.INFO)
    app = QApplication(sys.argv)
    window = MainWindow(app)
    window.show()
    app.exec()

if __name__ == '__main__':
    main()

问题原因

核心错误在于button.mapToGlobal(button.pos())这行代码:

  • button.pos()返回的是按钮在父容器中的相对位置(父坐标系下的坐标);
  • 而QWidget.mapToGlobal()方法要求传入的参数是当前widget自身坐标系内的点;
  • 用父坐标系的点去调用mapToGlobal(),会导致坐标转换时叠加两次父容器的偏移,最终计算出的全局坐标完全错误,导致tooltip显示到了错误位置。

修复方案

方案1:获取按钮左上角的正确全局坐标

将button_clicked方法中的point计算代码修改为:

from PyQt6.QtCore import QPoint  # 需要导入QPoint

def button_clicked(self, button: QPushButton, txt: str) -> None:
    # 获取按钮左上角的全局坐标
    point = button.mapToGlobal(QPoint(0, 0))
    logging.info(f"{txt} pos: {point}")
    QToolTip.showText(point, txt, msecShowTime=4000)

这样tooltip会显示在按钮的左上角位置。

方案2:让tooltip显示在按钮正上方(可选)

如果希望tooltip显示在按钮的正上方,可以调整y轴坐标,向上偏移按钮的高度:

from PyQt6.QtCore import QPoint

def button_clicked(self, button: QPushButton, txt: str) -> None:
    # 计算按钮正上方的全局坐标
    point = button.mapToGlobal(QPoint(0, -button.height()))
    QToolTip.showText(point, txt, msecShowTime=4000)

内容的提问来源于stack exchange,提问作者Håkon Hægland

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:48:25