我正在使用 Qt 的
QGraphicsView
— 和 QGraphicsItem
— 子类。
有没有办法在视图矩形更改时(例如放大时)不缩放视图中项目的图形表示形式。默认行为是我的项目相对于我的视图矩形进行缩放。
我想可视化二维点,这些点应该由一个细矩形表示,在放大视图时不应缩放。请参阅典型的 3D 建模软件以供参考,其中顶点始终以相同的大小显示。
将
QGraphicItem
的标志 QGraphicsItem::ItemIgnoresTransformations
设置为 true 对您不起作用?
扩展 QGraphicsItem 类,覆盖
paint()
。
在
paint()
内,将变换的缩放因子重置为1(即m11
和m22
),并在重置之前保存m11
(x缩放因子)和m22
(y缩放因子)。
然后,像平常一样绘制,但将 x 乘以
m11
,将 y 乘以 m22
。这避免了使用默认变换进行绘制,而是根据场景的变换显式计算位置。
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget)
{
QTransform t = painter->transform();
qreal m11 = t.m11(), m22 = t.m22();
painter->save(); // save painter state
painter->setTransform(QTransform(1, t.m12(), t.m13(),
t.m21(), 1, t.m23(), t.m31(),
t.m32(), t.m33()));
int x = 0, y = 0; // item's coordinates
painter->drawText(x*m11, y*m22, "Text"); // the text itself will not be scaled, but when the scene is transformed, this text will still anchor correctly
painter->restore(); // restore painter state
}
以下代码块使用默认变换进行绘制:
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget)
{
int x = 0, y = 0;
painter->drawText(x, y, "Text");
}
您可以尝试两者来看看差异。
这个怎么样:
#include <QtGui/QApplication>
#include <QtGui/QGraphicsScene>
#include <QtGui/QGraphicsView>
#include <QtGui/QGraphicsRectItem>
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
QGraphicsScene scene;
scene.addText("Hello, world!");
QRect rect(50, 50, 100, 100);
QGraphicsRectItem* recti = scene.addRect(rect);
QGraphicsView view(&scene);
// Set scale for the view
view.scale(10.0, 5.0);
// Set the inverse transformation for the item
recti->setTransform(view.transform().inverted());
view.show();
return app.exec();
}
如您所见,文本已放大,但矩形未放大。请注意,这不仅会阻止矩形的缩放,还会阻止其他变换。
以下解决方案对我来说非常有效:
void MyDerivedQGraphicsItem::paint(QPainter *painter, const StyleOptionGraphicsItem *option, QWidget *widget)
{
double scaleValue = scale()/painter->transform().m11();
painter->save();
painter->scale(scaleValue, scaleValue);
painter->drawText(...);
painter->restore();
...
}
我们还可以将scaleValue乘以我们希望在保存/恢复环境之外保持其大小恒定的其他度量。
QPointF ref(500, 500);
QPointF vector = scaleValue * QPointF(100, 100);
painter->drawLine(ref+vector, ref-vector);
我发现如果我派生一个新类并重新实现绘制函数我可以做到
void MyDerivedQGraphicsItem::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
double scaleValue = scale();
double scaleX = painter->transform().m11();
setScale(scaleValue / scaleX);
QGraphicsSvgItem::paint(painter,option,widget);
}
这是迄今为止我发现的最好的方法,但我仍在修改。