python - 判断点击事件中是哪个椭圆

标签 python pyqt pyqt5 qgraphicsview qgraphicsscene

我对 python 和 PyQT 非常陌生,并且陷入了困境。如果我的代码有点困惑,我深表歉意。我花了相当长的时间进行搜索,但还没有找到任何对我的情况有帮助的东西。

我正在尝试确定哪个椭圆被点击。

我基本上有一个部分,它在圆圈中创建椭圆并根据列表数组中的值在其上打印文本:

class MyFrame(QtWidgets.QGraphicsView):
    def __init__(self, parent = None ):
        super(MyFrame, self).__init__(parent)

        self.setScene(QtWidgets.QGraphicsScene())
        self.setBackgroundBrush(QtGui.QColor(QtCore.Qt.darkGray))
        self.setRenderHints(self.renderHints() | QtGui.QPainter.Antialiasing  | QtGui.QPainter.SmoothPixmapTransform)

        arLights = list( {} for i in xrange(12) )
        circX = 0
        circY = 0
        maxX = 0
        maxY = 0
        i = 0
        pen = QtGui.QPen(QtGui.QColor(QtCore.Qt.lightGray).darker(50))
        brush = QtGui.QBrush(QtGui.QColor(QtCore.Qt.lightGray))
        font = QtGui.QFont('White Rabbit')
        font.setPointSize(12)

        arLights = getLights()

        theta = radians(360)
        columns = len(filter(None, arLights))
        alpha = theta / columns

        for a in range(columns):
            angle = a * alpha
            circX = (w + x) * cos(angle)
            circY = (h + y) * sin(angle)

            item = callbackEllipse(circX, circY, w, h) #(x+xi*(w+x), y+yi*(h+y), w, h)
            item.setAcceptHoverEvents(True)
            item.setPen(pen)
            item.setBrush(brush)
            self.scene().addItem(item)
            item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)
            self.writeText(arrLight[i]['name'], circX + (w / 4), circY + (h * 0.75))
            i = i + 1

这是我的 mouseReleaseEvent,然后我尝试使用与该椭圆布局相同的公式计算出与该椭圆关联的名称。

class callbackEllipse(QtWidgets.QGraphicsEllipseItem):
    def mouseReleaseEvent(self, event):
        # recolor on click
        color = QtGui.QColor(QtCore.Qt.lightGray)
        brush = QtGui.QBrush(color)
        QtWidgets.QGraphicsEllipseItem.setBrush(self, brush)

        theta = radians(360)
        alpha = theta / arrRange

        arrLights = getLights()
        for a in xrange(0, len(filter(None, arrLights))):
            if (event.scenePos().x() > ((w + x) * cos(a * alpha))
                and event.scenePos().x() < (((w + x) * cos(a * alpha)) + w)
                and event.screenPos().y() < ((h + y) * sin(a * alpha))
                and event.screenPos().y() < (((h + y) * sin(a * alpha)) + h)
                ):
                print(arrLights[a]['name'])
                break

        return QtWidgets.QGraphicsEllipseItem.mouseReleaseEvent(self, event)

这没有按预期工作。我已经尝试过 .sceenPos() .screenPos() 和 .pos() 但它们似乎与我创建省略号时的坐标不匹配,导致它识别出错误的关联文本或找不到完全匹配。

任何人都可以帮助我找到一种识别椭圆的方法,或者为什么我的代码不能按我想要的方式工作?似乎没有办法给它们“命名”,这样会更容易。

最佳答案

不必要的时候不要工作2次,保存一个值引用并从mouseReleaseEvent()开始打印它仅当按下该项目时才会调用:

import math
from PyQt5 import QtCore, QtGui, QtWidgets

def getLights():
    return [{"name": str(i)} for i in range(10)]

class CallbackEllipse(QtWidgets.QGraphicsEllipseItem):
    def __init__(self, light, *args, **kwargs):
        super(CallbackEllipse, self).__init__(*args, **kwargs)
        self._light = light

    def mouseReleaseEvent(self, event):
        color = QtGui.QColor(QtCore.Qt.lightGray)
        brush = QtGui.QBrush(color)
        self.setBrush(brush)    
        print(self._light["name"])
        super(CallbackEllipse, self).mouseReleaseEvent(event)

class MyFrame(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(MyFrame, self).__init__(parent)

        self.setScene(QtWidgets.QGraphicsScene(self))
        self.setBackgroundBrush(QtGui.QColor(QtCore.Qt.darkGray))
        self.setRenderHints(self.renderHints() | QtGui.QPainter.Antialiasing  | QtGui.QPainter.SmoothPixmapTransform)

        arLights = getLights()

        theta = math.radians(360)
        filter_lights = list(filter(None, arLights)) 
        num_of_columns = len(filter_lights)
        delta = theta/num_of_columns
        circX, circY = 0, 0
        w, h, x, y = 100, 100, 100, 100

        pen = QtGui.QPen(QtGui.QColor(QtCore.Qt.lightGray).darker(50))
        brush = QtGui.QBrush(QtGui.QColor(QtCore.Qt.lightGray))

        for i, light in enumerate(filter_lights):
            angle = i*delta
            circX = (w + x) * math.cos(angle)
            circY = (h + y) * math.sin(angle)
            item = CallbackEllipse(light, circX, circY, w, h)
            item.setAcceptHoverEvents(True)
            item.setPen(pen)
            item.setBrush(brush)
            item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable)
            self.scene().addItem(item)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MyFrame()
    w.show()
    sys.exit(app.exec_())

关于python - 判断点击事件中是哪个椭圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53382602/

相关文章:

python - 将列从一个 Pandas DataFrame 映射到另一个

python - 登录系统时运行 Python 脚本? [xubuntu 15.04]

python - 如何从文本文件中随机删除 100 个 block

python - PyQt 清除菜单栏

python - 如何以整数形式检索 QLabel 值

python - PyQt5,多种颜色的Qlabel文本

python - 装饰器添加了一个意想不到的参数

python - Pandas :如何索引行?

python - pyqt QThread阻塞主线程

qt - 如何让顶部的QWidget模态化?