下面的代码显示了左侧的窗口(见下图)。但是,如果不注释标记为/*[identity transform]*/的行,则会生成右侧的窗口。正如控制台输出中的qInfo()所报告的那样,与坐标转换相关的任何内容似乎都没有更改。
有人能给我解释一下原因吗?我在documentation里找不到它。
class SomeItem : public QGraphicsEllipseItem
{
public:
explicit SomeItem(const QRectF& rect, QGraphicsItem* parent = nullptr) :
QGraphicsEllipseItem(rect,parent){}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
QTransform tr;
//painter->setWorldTransform(tr); /*[identity transform]*/
qInfo() << painter->window().left() << painter->window().right()
<< painter->window().top() << painter->window().bottom();
qInfo() << painter->viewport().left() << painter->viewport().right()
<< painter->viewport().top() << painter->viewport().bottom();
qInfo() << painter->matrix().m11() << painter->matrix().m12()
<< painter->matrix().m21() << painter->matrix().m22();
/* <--->*/
QGraphicsEllipseItem::paint(painter,option,widget);
}
};
int main(int argc, char **argv)
{
QApplication app (argc, argv);
QGraphicsScene ms;
ms.setSceneRect(-20,-20,40,40);
SomeItem* si = new SomeItem(QRectF(-10,-10,20,20));
ms.addItem(si);
QGraphicsView view(&ms);
view.show();
return app.exec();
}控制台输出(两种情况):
0 197 0 97
0 197 0 97
1 0 0 1

发布于 2019-03-22 01:35:13
在Marek's answer上的推理,我猜已经找到了一个几何解释。我的错误是检查painter->matrix()而不是painter->transform()。实际上,Qmatrix不管理翻译,而painter->transform().m31()和painter->transform().m32()管理翻译。
替换以下行
qInfo() << painter->transform().m31() << painter->transform().m32();代替/*<--->*/分别为这两种情况提供控制台输出,
99 49和
0 0发布于 2019-03-21 23:38:02
Paint方法使用局部坐标系。这意味着painter的原点通常位于QGraphicsItem的左上角(注意这是QGraphicsScene中所有东西的基类)。对于QGraphicsEllipseItem,它必须是它的中心。
显然,这是通过在处理void QWidget::paintEvent(QPaintEvent *event)时转换QGraphicsView小部件使用的QPainter来实现的。
简单地将QGraphicsScene中的每个QGraphicsItem都由QGraphicsView transform painter绘制,以满足其需要。
当您恢复身份转换时,您获得了一个应用于QGraphicsView paint事件的painter状态。所以它是它的左上角。
你很幸运,因为你是在boundingRect之外绘画,所以没有损坏。
https://stackoverflow.com/questions/55283613
复制相似问题