如何仅在 QPainted 对象上检测 Qt 鼠标事件

How to detect Qt mouse events only over QPainted objects

我正在尝试以编程方式生成一个看起来很像这样的指南针小部件:

我希望指南针的每个“切片”都充当一个按钮,用于与应用程序的其余部分进行交互。为此,我认为用 QAbstractButton 制作它们最合乎逻辑,并开始沿着这条路走下去:

class compassWedge(QAbstractButton):
    def __init__(self, start_angle, parent=None):
        super().__init__(parent)
        self.start = start_angle
        self.setFixedSize(550, 550)
        self.setMouseTracking(True)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        brush = QBrush()
        if self.underMouse():
            brush.setColor(Qt.black)
        else:
            brush.setColor(Qt.white)
        pen = QPen(Qt.black)
        pen.setWidth(5)
        painter.setBrush(brush)
        painter.setPen(pen)
        painter.drawPie(25, 25, 500, 500, self.start, 45 * 16)
        painter.end()


class compassApplet(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setFixedSize(550, 550)

        self.wedges = []
        for start in range(0, 360 * 16, 45 * 16):
            self.wedges.append(compassWedge(start, self))

从视觉上看,到目前为止效果很好:

问题是,对于 underMouse(),考虑了整个 550x550 切片小部件区域。相反,我想检测鼠标何时位于每个切片的 paintEvent 内生成的像素内,即每个对象中 painter.drawPie(...) 创建的饼图区域。

我怎样才能做到这一点而不必做复杂的几何图形来检查鼠标在饼形区域中的位置?

方法一:自己做几何计算:

How can I accomplish this without having to do complicated geometry to check mouse position against pie-shaped areas?

自己做几何检查并不难:

  1. 判断鼠标是否在圆内,即鼠标到圆心的距离<=圆的半径
  2. 使用atan2计算角度并使用它来确定正确的线段

方法二:使用QPieSeries

如果您真的不想自己进行几何计算,使用 QPieSeries 可视化指南针可能是一种解决方案,因为它提供了 hovered 功能。但是,可能(更)难以获得准确的所需视觉表示。