具有计算边界的问题

2024-07-04 08:17:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Qt5PySide2)和Qt4PySide)之间的行为差异感到困惑。我的印象是Qt5有一个bug,但也许我做错了什么

简而言之:当将计算的QPainterPath应用于QGraphicsPathItem(使用setPath)时,QGraphicsPathItem的结果大小比QPainterPath本身的大小大1.5像素。这对我来说毫无意义,Qt4的尺寸完全一样

我提供了一段简单的代码,可以用PySide和PySide2进行复制

使用PySide:

#!/usr/bin/env python2

from PySide.QtCore import *
from PySide.QtGui import *

class Foo (QGraphicsPathItem):
    def __init__(self, parent):
        super(Foo, self).__init__()
        path = QPainterPath()
        path.addRect(0,0,10,10)
        print(str(path.boundingRect()))
        self.setPath(path)
        print(str(self.boundingRect()))

x=Foo(None)

结果是:

$ python2 ./with_py2.py 
PySide.QtCore.QRectF(0.000000, 0.000000, 10.000000, 10.000000)
PySide.QtCore.QRectF(0.000000, 0.000000, 10.000000, 10.000000)

和预期的一样大。一切都很好

与Qt5完全相同的代码:

#!/usr/bin/env python3

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *

class Foo (QGraphicsPathItem):
    def __init__(self, parent):
        super(Foo, self).__init__()
        path = QPainterPath()
        path.addRect(0,0,10,10)
        print(str(path.boundingRect()))
        self.setPath(path)
        print(str(self.boundingRect()))

x=Foo(None)

结果:

$ python3 bug.py 
PySide2.QtCore.QRectF(0.000000, 0.000000, 10.000000, 10.000000)
PySide2.QtCore.QRectF(-0.500000, -0.500000, 11.000000, 11.000000)

有人看到什么明显的解释吗

谢谢


Tags: pathfromimportselffooinitpysideprint
1条回答
网友
1楼 · 发布于 2024-07-04 08:17:47

boundingRect依赖于QGraphicsPathItem的QPen来计算它,如源代码中所示

Qt4

QRectF QGraphicsPathItem::boundingRect() const
{
    Q_D(const QGraphicsPathItem);
    if (d->boundingRect.isNull()) {
        qreal pw = pen().widthF();
        if (pw == 0.0)
            d->boundingRect = d->path.controlPointRect();
        else {
            d->boundingRect = shape().controlPointRect();
        }
    }
    return d->boundingRect;
}

Qt5

QRectF QGraphicsPathItem::boundingRect() const
{
    Q_D(const QGraphicsPathItem);
    if (d->boundingRect.isNull()) {
        qreal pw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF();
        if (pw == 0.0)
            d->boundingRect = d->path.controlPointRect();
        else {
            d->boundingRect = shape().controlPointRect();
        }
    }
    return d->boundingRect;
}

如果您检查两个版本中的Qt文档,您将看到默认创建的QPen的值发生了变化:

The default pen is a solid black brush with 0 width, square cap style (Qt::SquareCap), and bevel join style (Qt::BevelJoin).

(我的重点)

The default pen is a solid black brush with 1 width, square cap style (Qt::SquareCap), and bevel join style (Qt::BevelJoin).

(我的重点)

如果您想观察PySide2中的PySide行为,那么将QPen(Qt::NoPen)设置为QGraphicsPathItem

class Foo(QGraphicsPathItem):
    def __init__(self, parent=None):
        super(Foo, self).__init__(parent)
        self.setPen(QPen(Qt.NoPen))
        path = QPainterPath()
        path.addRect(0, 0, 10, 10)
        print(str(path.boundingRect()))
        self.setPath(path)
        print(str(self.boundingRect()))


x = Foo()

输出

PySide2.QtCore.QRectF(0.000000, 0.000000, 10.000000, 10.000000)
PySide2.QtCore.QRectF(0.000000, 0.000000, 10.000000, 10.000000)

相关问题 更多 >

    热门问题