我在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中的位置引起的,則可以通過調用它而不是事件循環的不同部分來避免該故障。您需要一種方法來傳遞比例參數;也許通過將其存儲在一個成員變量中。 –