我在Windows与Qt 4.7。QGraphicsView缩放后冻结
我在我的qgraphicsview
/qgraphicsscene
中有一个错误,在缩放视图后,某些东西导致“挂起”,这在事件循环中似乎是一个递归/无限循环。
我很抱歉没有一个简单的,完整的代码示例;我将描述的症状,情况,尽我所能,而且我希望有人将有一个或两个想法,我可以尝试:
我有子类QGraphicsView
,QGraphicsScene
和QGraphicsItem
。例如,wheelEvent
在QGraphicsView
已经子类执行以下操作:
scaleView(pow((double)2, -event->delta()/240.0));
其中
void MyGraphicsView::scaleView(qreal scaleFactor)
{
qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
if (factor < 0.07 || factor > 100)
return;
scale(scaleFactor, scaleFactor);
}
我graphicsview
子类的构造函数如下:
MyGraphicsView(QWidget *parent) :
QGraphicsView(parent)
{
setRenderHint(QPainter::Antialiasing);
setTransformationAnchor(AnchorUnderMouse);
setCacheMode(QGraphicsView::CacheNone);
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
setDragMode(QGraphicsView::ScrollHandDrag);
}
我的QGraphicsItem的子类构造函数如下:
MyGraphicsItem(QGraphicsObject *parent) :
QGraphicsObject(parent),
_colour(qrand() % 256, qrand() % 256, qrand() % 256),
_collapsed(false)
{
setFlag(ItemIsMovable);
setFlag(ItemSendsGeometryChanges);
setCacheMode(DeviceCoordinateCache);
setZValue(-1);
expandedPosition(this->pos());
}
我可以将问题隔离为致电wheelEvent
或调用QGraphicsView::scaleView
的其他事件。
如果有一个MyGraphicsItem
可见,然后尝试绘画(或由绘画造成的东西)导致整个系统挂起。我认为这是在事件循环的循环,而是要摆脱它(CTRL + ALT + 德尔,弹出“启动任务管理器”,然后ESC取消)我失去了环路我在
该循环似乎是重复呼叫QGraphicsView::focusInEvent
和focusOutEvent
。我已经重写了这些,并且在停止循环方面似乎没有太多的运气,不管我使用这些函数做什么。
编辑:这似乎是一个红色的鲱鱼,切换到调试器内的断点的结果。
如果视图未显示MyGraphicsItem
,则不存在问题。
还有,我可以在缩放后重新绘制视图,但试图调整窗口大小或改变焦点会导致问题。
同样,如果还没有打电话给scaleView
,我没有问题。
也许我太模糊了;但请解答任何我可以帮助澄清的问题。任何帮助感谢! 更新:
所以我似乎已经把它归结为我的子类的QGraphicsItem的一个子类。
我从弹性节点的例子中得到一个节点,并把它放在我的场景中。我可以放大和缩小使用我的场景和视图,并且不会挂起。
我甚至可以让Node成为MyGraphicsItem的一个子类而不是QGraphicsItem,并且再次没有任何问题。
只要我将MyGraphicsItem的子类放入场景中,我就会看到问题。 靠近我希望!
尝试升级你的Qt - 你有一个古老的版本。这些错误通常在后续版本中修复。 –
我不能随便改变Qt版本;这是在一个生产环境中,改变Qt版本是相当重要的:-) – mike
最好尝试找出实际发生了什么(如果没有别的东西,通过printf()样式调试),但如果其他您可能想尝试将您的scaleView()调用移至单独的上下文,例如失败通过调用QTimer :: singleShot(0,this,SLOT(myScaleViewSlot())),而不是直接从处理程序调用scaleView()。这样,如果故障是由调用scaleView()的event-loop中的位置引起的,则可以通过调用它而不是事件循环的不同部分来避免该故障。您需要一种方法来传递比例参数;也许通过将其存储在一个成员变量中。 –