Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将QLabel在QGraphicscene中的GGraphicsEllipseItem的中心对齐 我想知道在我的饼图中是否有一种方法可以将QLable定位在“扇区”的中间,这是我和PyQt一起设计的。扇区是QGraphicsSellipseitems,我已经为其分配了相应的起始角和跨度角。到目前为止,我已经尝试将标签放在QGraphicsProxy项目中,并将“切片”或“扇区”设置为父项。然后,我试着把标签放在“扇区”的中间。然而,问题是boundingRect是一个矩形,而不仅仅是“扇区”本身_Python_Pyqt_Pyqt5_Qgraphicsitem - Fatal编程技术网

Python 将QLabel在QGraphicscene中的GGraphicsEllipseItem的中心对齐 我想知道在我的饼图中是否有一种方法可以将QLable定位在“扇区”的中间,这是我和PyQt一起设计的。扇区是QGraphicsSellipseitems,我已经为其分配了相应的起始角和跨度角。到目前为止,我已经尝试将标签放在QGraphicsProxy项目中,并将“切片”或“扇区”设置为父项。然后,我试着把标签放在“扇区”的中间。然而,问题是boundingRect是一个矩形,而不仅仅是“扇区”本身

Python 将QLabel在QGraphicscene中的GGraphicsEllipseItem的中心对齐 我想知道在我的饼图中是否有一种方法可以将QLable定位在“扇区”的中间,这是我和PyQt一起设计的。扇区是QGraphicsSellipseitems,我已经为其分配了相应的起始角和跨度角。到目前为止,我已经尝试将标签放在QGraphicsProxy项目中,并将“切片”或“扇区”设置为父项。然后,我试着把标签放在“扇区”的中间。然而,问题是boundingRect是一个矩形,而不仅仅是“扇区”本身,python,pyqt,pyqt5,qgraphicsitem,Python,Pyqt,Pyqt5,Qgraphicsitem,海图 在上图中,您可以看到问题所在。标签的位置不正确。我正试图通过标签实现以下目标: 标签位于正确位置的模型图表 当前代码: pie = QtWidgets.QGraphicsEllipseItem(60, 110, self.piechart.width, self.piechart.height) pie.setTransformOriginPoint(pie.boundingRect().center()) pie.setZValue(-1) self.

海图

在上图中,您可以看到问题所在。标签的位置不正确。我正试图通过标签实现以下目标:

标签位于正确位置的模型图表

当前代码:

    pie = QtWidgets.QGraphicsEllipseItem(60, 110, self.piechart.width, self.piechart.height)
    pie.setTransformOriginPoint(pie.boundingRect().center())
    pie.setZValue(-1)
    self.scene.addItem(pie)

    start_angle = 0


    for sector in self.piechart.sectors:
        slice = QtWidgets.QGraphicsEllipseItem(60, 110, self.piechart.width, self.piechart.height, parent=pie)
        color = QtGui.QBrush(sector.color)
        slice.setBrush(color)
        span_angle = sector.proportional_volume*360*16
        slice.setStartAngle(start_angle)
        slice.setSpanAngle(span_angle)
        start_angle += span_angle

        label = QtWidgets.QLabel(str(round(sector.proportional_volume*100,2))+'%', alignment = QtCore.Qt.AlignCenter)
        label.setAutoFillBackground(False)
        label.setStyleSheet('background-color: transparent')
        font = QtGui.QFont('Times', 8)
        font.setBold(True)
        label.setFont(font)

        proxy = QtWidgets.QGraphicsProxyWidget(slice)
        proxy.setWidget(label)
        proxy.setPos(slice.boundingRect().center()) 

        self.scene.addItem(slice)
        self.scene.addItem(proxy)

由于几何原因(根据基本定义),不能使用边界矩形的中心:

这个纯虚函数将项的外部边界定义为矩形

这意味着无论项目的形状是什么,边界矩形都是一个包含项目整体形状的矩形。
在下图中,您可以清楚地看到“这不是您要找的中心”[cit.]:

你实际上需要的是每个切片的中间轴的中心,所以只需要将切片的一半除以一半,并使用半径的一半。

请注意,图形项目(就像小部件一样)通常使用其左上角作为其位置的参考,如果使用“中间”作为参考,则不会得到正确的结果:

为了避免这种情况,您必须减去标签矩形的中心,以便它正确居中于您想要的位置

        # create a common rectangle, since we're going to use the same coordinates
        # for all ellipses
        rect = QtCore.QRectF(60, 110, self.piechart.width, self.piechart.height)
        pie = QtWidgets.QGraphicsEllipseItem(rect)
        pie.setTransformOriginPoint(pie.boundingRect().center())
        pie.setZValue(-1)
        self.scene.addItem(pie)

        # the center position is half of the radius, or a quarter of the size
        labelRadius = self.piechart.width * .25
        center = rect.center()
        start_angle = 0


        for sector in self.piechart.sectors:
            slice = QtWidgets.QGraphicsEllipseItem(rect, parent=pie)
            slice.setPen(QtGui.QPen(QtCore.Qt.NoPen))
            color = QtGui.QBrush(sector.color)
            slice.setBrush(color)
            span_angle = sector.proportional_volume*360*16
            slice.setStartAngle(start_angle)
            slice.setSpanAngle(span_angle)
            # we need the current start_angle later, let's do this later
            # start_angle += span_angle

            label = QtWidgets.QLabel(str(round(sector.proportional_volume*100,2))+'%', alignment = QtCore.Qt.AlignCenter)
            label.setAutoFillBackground(False)
            label.setStyleSheet('background-color: transparent')
            font = QtGui.QFont('Times', 8)
            font.setBold(True)
            label.setFont(font)

            proxy = QtWidgets.QGraphicsProxyWidget(slice)
            proxy.setWidget(label)

            # get the middle angle of the slice
            angle = start_angle / 16 + sector.proportional_volume * 180

            # create a line that has a length that's a quarter of the radius, and
            # has an angle that is in the middle of the current slice; finally,
            # get its end point (p2)
            line = QtCore.QLineF.fromPolar(labelRadius, angle)
            middlePoint = line.p2()

            # the above can also be achieved by using trigonometry functions; note
            # that the sine is negative, since QGraphicsScene coordinates are
            # inverted vertically (downwards coordinates are positive)
            # x = cos(radians(angle)) * labelRadius
            # y = -sin(radians(angle)) * labelRadius
            # middlePoint = QtCore.QPointF(x, y)

            # finally, translate the point to the center of the ellipse
            middlePoint += center
            r = QtCore.QRectF(-1, -1, 2, 2)
            self.scene.addEllipse(r.translated(middlePoint))

            # center the label at that point by subtracting its own center
            proxy.setPos(middlePoint - label.rect().center())

            start_angle += span_angle

            # when you create a QGraphicsItem with a parent that has already been
            # added to the scene, there's no need to add it again
            # self.scene.addItem(slice)
            # self.scene.addItem(proxy)
考虑到从图形的角度来看,由于基于切片几何结构和字符视觉感知的视错觉,实际“中间”位置通常会被认为更靠近中心;下图基于上述代码,如您所见,右侧的浅绿色小切片(4.76%)看起来有偏移,即使它正确居中:

因此,您可能更愿意为
labelRadius
使用稍高的比率(例如,0.3)

最后,有两个考虑:

  • 某些百分比可能非常小,您可能会在下一个切片中部分隐藏某些标签;您可能更希望避免将标签作为切片的子对象
  • 使用QGrimeCsPro XixWIGET对于简单的QLaby是不必要的,考虑使用或仔细阅读它们的文档,因为它们的坐标系统不完全以相同的方式运行。