PyQt技术问题:点击按钮时QToolTip定位错误如何修正?
问题描述
点击「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
相关产品推荐
相关产品推荐

