【发布时间】:2012-07-16 17:23:31
【问题描述】:
我有一个从 QGraphicsView 派生的自定义类,它实现了一个 slot 调用 scrollHorizontal(int dx),里面的代码很简单
void CustomView::scrollHorizontal(int dx){
scrollContentsBy(dx, 0);
}
我的问题是,像这样滚动有效,但不能正确更新场景,而是重复在视图边缘找到的任何像素,而不是重新调用项目的 paint() 方法。
之后我尝试调用update(),但没有任何反应。我尝试通过拖动启用滚动并且更新工作正常!但我需要以编程方式完成它,因为我有滚动条隐藏了 horizontalScrollBar()->setValue() 之类的东西,所以不要滚动视图。
我也试过了:
scrollContentsBy(dx, 0);
this->scene()->invalidate(sceneRect());
this->update();
更新:
QPointF center = mapToScene(viewport()->rect().center());
centerOn(center.x() - dx, center.y());
update();
正在工作,但现在我的顶视图滚动速度比底视图慢,这是一个新问题。它们与signals 和slots 链接,在底部视图中我将scrollContentsBy(int dx, int dy) 覆盖为emit horizontalScroll(dx);上面的slot在顶视图中捕捉到了。
任何想法为什么卷轴以不同的速度发生?滚动条可能与作为底部视图的一部分有效地使其成为“较小”窗口有关吗?
更新 2:
不同的滚动率似乎源于一些舍入,使用 mapToScene(viewport()->rect().center()); 给我一个基于整数的“中心”,当您滚动时,滚动速度越慢,此错误加起来越多,滚动速度越快,总数越少错误。
我有办法解决这个问题吗?我没有看到任何方法来获得浮点中心点。
更新 3:
所以我基本上解决了这个问题,结果证明需要 mapToScene(我在网上其他地方找到的代码)。
我通过存储 FP 计算的视口中心的 QPointF 来解决此问题,现在滚动两个视图时的错误量不明显。
最后一个问题是,当您向右滚动任意数量,然后调整窗口大小然后再次滚动时,视图不再排列。我认为这与计算中心点和居中发生时间的逻辑顺序有关。
现在我在 QGraphicsScene::ResizeEvent() 和其他地方使用以下代码 sn-p 来根据需要更新中心
QRectF viewPort(viewport()->rect());
QPointF rectCenter((viewPort.x() + viewPort.x() + viewPort.width())/2.0, (viewPort.y() + viewPort.y() + viewPort.height())/2.0);
viewCenter = rectCenter;
还有我的horizontalScroll(int dx)slot
void CustomView::horizontalScroll(int dx)
{
viewCenter.setX(viewCenter.x() - dx);
centerOn(viewCenter.x(), viewCenter.y());
update();
}
如何解决在重新调整窗口大小时破坏两个视图对齐的问题?如果需要进一步澄清,请尽管问,如果需要,我可以尝试给出我所指的内容的骨架。
更新 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
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 : 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);
}
}
类 MainWindow 中的某处:
connect(eventView, SIGNAL(horizontalScroll(int)), headerView, SLOT(horizontalScroll(int));
【问题讨论】:
-
我真的很想看一下重现此代码的最小示例。
-
我也认为最好的办法是创建一个最小的示例代码。只有这两种观点有联系。你能做这个吗?这会有很大帮助。也许您会在这样做的同时找到解决方案,这种情况经常发生。 ;)
标签: c++ qt user-interface graphics scroll