程序化QGraphicsView滚动不能正确更新 [英] Programmatic QGraphicsView scrolling not updating properly

查看:1287
本文介绍了程序化QGraphicsView滚动不能正确更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义类派生自QGraphicsView实现一个插槽调用scrollHorizo​​ntal(int dx),在代码里是简单的

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);
}

我的问题是,这样的滚动会正常工作, ,而不是对视图的边缘上发现的任何像素重复,而不是对项目的 paint()方法进行新的调用。

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.

我之前尝试调用 update(),但什么也没有发生。我试图通过拖动和更新工作启用滚动!但是我需要通过编程方式,并且因为我有滚动条隐藏的东西像 horizo​​ntalScrollBar() - > setValue()不滚动视图。

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.

我也尝试过:

scrollContentsBy(dx, 0);
this->scene()->invalidate(sceneRect());
this->update();

更新:

QPointF center = mapToScene(viewport()->rect().center()); 
centerOn(center.x() - dx, center.y()); 
update(); 

正在工作,但现在我的顶视图滚动比我的底视图慢,这是一个新问题。它们与信号 s和 slot 链接,在底部视图中,我有 scrollContentsBy int dx,int dy)覆盖发射horizo​​ntalScroll(dx);

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?

更新2:

不同的滚动率似乎源自一些舍入发生,给我一个整数为基础的中心使用 mapToScene(viewport() - > rect )); ,当你滚动和滚动越慢这个错误加起来越多,滚动越少的总错误。

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.

更新3:

这个主要是解决了,结果是需要mapToScene(我在网上其他地方找到的代码)。

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

我通过存储 QPointF of FP计算视口的中心,现在滚动这两个视图时的错误量是不引人注意的。

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.

现在我使用下面的代码片段 QGraphicsScene :: ResizeEvent()和其他地方根据需要更新中心

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;

和我的 horizo​​ntalScroll(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.

更新4:

粗糙代码骷髅

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

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();
}

类EventView:

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

EventView.cpp

void EventView::scrollContentsBy(int dx, int dy)
{
    QGraphicsView::scrollContentsBy(dx, dy);

    if(dx != 0){
        emit horizontalScroll(dx);
    }
}

在MainWindow类中:

Somwhere in Class MainWindow:

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


推荐答案

我在Qt中使用了 QGraphicsView 4.6.3 - 4.7.2,并且必须以下列方式论证您可以使用相应的 QScrollBar

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);

它们是否隐藏并不重要。只要您的图形场景大于图形视图,它们仍然会响应 setValue(int)

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.

QGraphicsView 也会响应 ensureVisible ,这会将滚动条移动到相应的位置。

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

这篇关于程序化QGraphicsView滚动不能正确更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆