qgraphicsview刷新,程序化QGraphicsView滚动不能正确更新

I have a custom class derived from QGraphicsView that implements a slot call scrollHorizontal(int dx), inside the code is simply

void CustomView::scrollHorizontal(int dx){

scrollContentsBy(dx, 0);

}

My problem is, scrolling like this works but doesn't update the scene properly, instead any pixels found on the edge of the view are repeated instead of having a fresh call to the item's paint() method.

I've attempted calling update() after, but nothing happens. I tried enabling scrolling by dragging and updates work fine! But I need it done programmatically, and since I have the scroll bars hidden things like horizontalScrollBar()->setValue() do not scroll the view.

I also tried :

scrollContentsBy(dx, 0);

this->scene()->invalidate(sceneRect());

this->update();

update:

QPointF center = mapToScene(viewport()->rect().center());

centerOn(center.x() - dx, center.y());

update();

is working, but now my top view is scrolling slower than my bottom view, which is a new problem. They are linked with signals and slots, in the bottom view i have scrollContentsBy(int dx, int dy) overrided to emit horizontalScroll(dx); which is caught by the above slot in the top view.

Any ideas why the scrolls happen at different rates? Might it have something to do with the scroll bars being a part of the bottom view effectively making it a "smaller" window?

update 2:

The different scroll rates seems to stem from some rounding happening to give me an integer based "center" using mapToScene(viewport()->rect().center()); , as you scroll and the slower you scroll the more this error adds up, the faster you scroll the less total error.

Is there a way for me to get around this? I don't see any way to get a floating point center point.

update 3:

So I have this mostly solved, turns out the mapToScene was needed(code I found elsewhere on the web).

I fixed this by storing QPointF of FP calculated center of the viewport, now the amount of error when scrolling the two views is unnoticeable.

The final issue is, the views no longer line up when you scroll ANY amount to the right, and then resize the window then scroll again. I assume this has something to do with the logical ordering of when the center point is calculated and when the centering happens.

Right now I use the following code snippet in QGraphicsScene::ResizeEvent() and elsewhere that updates the center as needed

QRectF viewPort(viewport()->rect());

QPointF rectCenter((viewPort.x() + viewPort.x() + viewPort.width())/2.0, (viewPort.y() + viewPort.y() + viewPort.height())/2.0);

viewCenter = rectCenter;

and my horizontalScroll(int dx) slot

void CustomView::horizontalScroll(int dx)

{

viewCenter.setX(viewCenter.x() - dx);

centerOn(viewCenter.x(), viewCenter.y());

update();

}

How can I fix the issue when re-sizing the window breaking the alignment of the two views? If any more clarification is needed please just ask, I can try to give skeletons of what I'm referring to if need be.

Update 4:

Rough code Skeleton

Class HeaderView:

class HeaderView View : public QGraphicsView

{

Q_OBJECT

public:

HeaderView(QWidget * parent = 0);

HeaderView(QGraphicsScene * scene, QWidget * parent = 0);

private:

QPointF viewCenter;

protected:

void resizeEvent ( QResizeEvent * event );

public slots:

void horizontalScroll(int);

void addModel(qreal, qreal, const QString&);

};

HeaderView.cpp

void HeaderView::resizeEvent(QResizeEvent *event)

{

QGraphicsView::resizeEvent(event);

QRectF viewPort(viewport()->rect());

QPointF rectCenter((viewPort.x() + viewPort.x() + viewPort.width())/2.0, (viewPort.y() + viewPort.y() + viewPort.height())/2.0);

viewCenter = rectCenter;

}

void HeaderView::horizontalScroll(int dx)

{

viewCenter.setX(viewCenter.x() - dx);

centerOn(viewCenter.x(), viewCenter.y());

update();

}

Class EventView:

class EventView : public QGraphicsView

{

Q_OBJECT

public:

EventView(QWidget * parent = 0);

EventView(QGraphicsScene * scene, QWidget * parent = 0);

QRectF visibleRect();

protected:

void scrollContentsBy ( int dx, int dy );

signals:

void horizontalScroll(int);

};

EventView.cpp

void EventView::scrollContentsBy(int dx, int dy)

{

QGraphicsView::scrollContentsBy(dx, dy);

if(dx != 0){

emit horizontalScroll(dx);

}

}

Somwhere in Class MainWindow:

connect(eventView, SIGNAL(horizontalScroll(int)), headerView, SLOT(horizontalScroll(int));

解决方案

I've worked with QGraphicsView in Qt 4.6.3 - 4.7.2 and have to argue that you can use the respective QScrollBar in the following way:

//graphics view initialization

QGraphicsView *graphicsView = new QGraphicsView(parent);

QGraphicsScene *scene = new QGraphicsScene(0,0,widthOfScene,heightOfScene,parent);

graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

graphicsView->setScene(scene);

//in another method

QScrollBar* yPos=graphicsView->verticalScrollBar();

yPos->setValue((int) newValue);

It does not matter if they are hidden or not. They will still respond to setValue(int) as long as you have a graphics scene that is larger than the graphics view.

The QGraphicsView will also respond to ensureVisible, which moves the scrollbars to the appropriate location.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值