如果将鼠标悬停在小部件的特定区域上,则更改光标

Change the cursor if hovered over a particular region of a widget

我创建了一个自定义小部件,我在其中绘制了一个小三角形。我想知道如果将鼠标悬停在我在小部件上绘制的三角形上是否可以更改光标。

注意:我曾尝试使用 mouseMoveEvent,但除非单击,否则它不会更新。我也试过 eventFilter 但看起来它甚至没有进入那个方法。

这里是类似代码不一样。三角形在底部。我希望光标在红色三角形上方时自动更新

from PyQt5.QtCore import Qt, QPoint, QPointF, QEvent
from PyQt5.QtGui import QPainter, QIcon, QColor
from PyQt5.QtWidgets import *
from PyQt5 import QtCore
import sys


class Stack(QWidget):

    def __init__(self, parent=None):

        super(Stack, self).__init__(parent)
        self.cursor_x = [x for x in range(self.width() - 20, self.width())]
        self.cursor_y = [y for y in range(self.height() - 20, self.height())]


    def paintEvent(self, event):
        
        super(Stack, self).paintEvent(event)
        qp = QPainter(self)
    
        qp.setPen(Qt.white)

        qp.setBrush(Qt.white)
        qp.drawRect(10, 10, 150, 150)

        p = QPointF(self.width() - 20, self.height() - 10)
        q = QPointF(self.width() - 10, self.height() - 20)
        r = QPointF(self.width() - 10, self.height() - 10)

        qp.setPen(Qt.white)
        qp.setBrush(Qt.red)
        qp.drawPolygon(p, q, r)

    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            if event.x() in self.cursor_x and event.y() in self.cursor_y:
                print('yes')
                self.setCursor(QtCore.Qt.SizeFDiagCursor)

        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if event.x() in self.cursor_x and event.y() in self.cursor_y:

            self.setCursor(QtCore.Qt.SizeFDiagCursor)
        super(Stack, self).mouseMoveEvent(event)
        
    def eventFilter(self, obj, event):
        print(event)
        print('hello')
        if obj is self and event.type() == QEvent.HoverEnter:
            print("Mouse is over the label")

        super().eventFilter(event)

    def mouseReleaseEvent(self, event):
        if event.x() not in self.cursor_x and event.y() not in self.cursor_y:
            self.unsetCursor()
            super(Stack, self).mouseReleaseEvent(event)
    
if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = Stack()
    win.show()
    sys.exit(app.exec_())

当光标在区域之外时,您也必须停用光标。对于 mouseMoveEvent,您必须启用 mouseTracking 属性。最后我使用 QPolygon 来检查光标是在矩形内部还是外部:

class Stack(QWidget):
    def __init__(self, parent=None):

        super(Stack, self).__init__(parent)
        self._triangle = QPolygon()
        self.setMouseTracking(True)

    def _recalculate_triangle(self):
        p = QPoint(self.width() - 20, self.height() - 10)
        q = QPoint(self.width() - 10, self.height() - 20)
        r = QPoint(self.width() - 10, self.height() - 10)
        self._triangle = QPolygon([p, q, r])
        self.update()

    def resizeEvent(self, event):
        self._recalculate_triangle()

    def paintEvent(self, event):
        super(Stack, self).paintEvent(event)
        qp = QPainter(self)

        qp.setPen(Qt.white)

        qp.setBrush(Qt.white)
        qp.drawRect(10, 10, 150, 150)

        qp.setPen(Qt.white)
        qp.setBrush(Qt.red)
        qp.drawPolygon(self._triangle)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton and self._triangle.containsPoint(
            event.pos(), Qt.OddEvenFill
        ):
            self.setCursor(Qt.SizeFDiagCursor)
        else:
            self.unsetCursor()

    def mouseMoveEvent(self, event):
        if self._triangle.containsPoint(event.pos(), Qt.OddEvenFill):
            self.setCursor(Qt.SizeFDiagCursor)
        else:
            self.unsetCursor()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton and self._triangle.containsPoint(
            event.pos(), Qt.OddEvenFill
        ):
            self.setCursor(Qt.SizeFDiagCursor)
        else:
            self.unsetCursor()