AttributeError: 'QHoverEvent' object has no attribute 'x'

AttributeError: 'QHoverEvent' object has no attribute 'x'

我正在尝试使用 QLabel 显示一种 QToolTip,以在光标位于小部件上时显示消息,在本例中为 QPushButton

为此,我想到在 QPushButton 中输入一个事件过滤器,如果事件等于 Hover,那么它会启动 mouseMoveEvent 函数。

问题是该消息随处显示,但是当进入 QPushButton 时,程序停止并抛出此错误:

Traceback (most recent call last):
  File "C:\Users\Angel\Desktop\Hover.py", line 22, in eventFilter
    self.mouseMoveEvent(event)
  File "C:\Users\Angel\Desktop\Hover.py", line 26, in mouseMoveEvent
    print(event.x())
AttributeError: 'QHoverEvent' object has no attribute 'x'

目的是仅当光标进入小部件时才显示消息

这是我的代码

from PyQt5.QtWidgets import QMainWindow,QApplication,QPushButton,QLabel
from PyQt5 import QtCore

class Hover(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.customToolTip = QLabel(self)

        self.button = QPushButton(self)
        self.button.setText("Button1")
        self.button.installEventFilter(self)

        self.setMouseTracking(True)


    def eventFilter(self,object,event):
        if event.type() == QtCore.QEvent.MouseButtonPress:
            print("Pressed")
            return True
        elif event.type() == QtCore.QEvent.HoverEnter:
            self.mouseMoveEvent(event)
            return True
        return False
    def mouseMoveEvent(self,event):
        print(event.x())

        self.customToolTip.setText("Otro texto")
        self.customToolTip.setStyleSheet("background:red;border-radius:5px;")
        self.customToolTip.move(QtCore.QPoint(event.x(),event.y()))
        self.customToolTip.adjustSize()
        self.customToolTip.show()



app = QApplication([])
h = Hover()
h.show()
h.resize(800,600)
app.exec_()

简单但不推荐的解决方案是更改:

self.customToolTip.move(QtCore.QPoint(event.x(),event.y()))

self.customToolTip.move(event.pos())

因为QHoverEvent没有x()方法,如果要获取位置必须使用pos()方法

不推荐,因为您正在向不应处理的方法发送事件,也许在这种情况下它可以工作,但将来可能会给您带来问题。

你的问题中有以下不恰当的短语:启动mouseMoveEvent函数,HoverEnter只在进入widget时触发,中间不再触发该事件,所以如果你想显示工具提示,这不是最合适的。

如果您希望工具提示仅显示在 QPushButton 中,您必须执行以下操作:

  • 在按钮上启用鼠标跟踪。
  • 使用 MouseMove 事件。
  • 使 QLabel 成为按钮的子项...
class Hover(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(Hover, self).__init__(parent)

        self.button = QtWidgets.QPushButton(self)
        self.customToolTip = QtWidgets.QLabel(self.button)
        self.button.installEventFilter(self)
        self.button.setMouseTracking(True)
        self.button.setText("Button1")

    def eventFilter(self, obj, event):
        if event.type() == QtCore.QEvent.MouseMove and self.button is obj:
            self.handle_tooltip(event.pos())
        return super(Hover, self).eventFilter(obj, event)

    def handle_tooltip(self, pos):
        self.customToolTip.setText("Otro texto")
        self.customToolTip.setStyleSheet("background:red;border-radius:5px;")
        self.customToolTip.move(pos)
        self.customToolTip.adjustSize()
        self.customToolTip.show()

之前的方法有一个缺点,因为widget的children只会在与parent的交集处绘制,如果文本太长或者鼠标远离中心,QLabel将不会完全显示,为避免这种情况,除了使用 mapToGlobal():

将本地位置转换为全局位置外,还必须启用标志 Qt::ToolTip
class Hover(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(Hover, self).__init__(parent)

        self.button = QtWidgets.QPushButton(self)
        self.customToolTip = QtWidgets.QLabel(
            self.button, flags=QtCore.Qt.ToolTip
        )
        self.button.installEventFilter(self)
        self.button.setMouseTracking(True)
        self.button.setText("Button1")

    def eventFilter(self, obj, event):
        if event.type() == QtCore.QEvent.MouseMove and self.button is obj:
            self.handle_tooltip(event.pos())
        return super(Hover, self).eventFilter(obj, event)

    def handle_tooltip(self, pos):
        gp = self.button.mapToGlobal(pos)
        self.customToolTip.setText("Otro texto")
        self.customToolTip.setStyleSheet("background:red;border-radius:5px;")
        self.customToolTip.move(gp)
        self.customToolTip.adjustSize()
        self.customToolTip.show()