如何仅通过QPainted对象检测Qt鼠标事件

问题描述

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

Compass widget target

我希望指南针的每个“切片”都充当与应用程序其余部分进行交互的按钮。为此,我认为将它们从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,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))

从视觉上看,到目前为止,它是完美的:

Work in progress

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

如何做到这一点而不必做复杂的几何图形来检查鼠标相对于饼状区域的位置?

解决方法

方法1:自己执行几何计算:

如何做到这一点而不必做复杂的几何图形来检查鼠标相对于饼状区域的位置?

自己进行几何检查并不困难:

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

方法2:使用QPieSeries

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