スロット呼び出しscrollHorizontal(int dx)を実装するQGraphicsViewから派生したカスタムクラスがあります。コード内は単純です
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();
動作していますが、トップビューのスクロールがボトムビューよりも遅くなりました。これは新しい問題です。それらはsignal
s とslot
s にリンクされており、下のビューでscrollContentsBy(int dx, int dy)
オーバーライドしましたemit horizontalScroll(dx)
。これはslot
、上図で捉えたものです。
スクロールが異なる速度で発生する理由はありますか? スクロールバーがボトムビューの一部であり、効果的に「小さい」ウィンドウになっていることに関係している可能性がありますか?
更新 2:
スクロール速度が異なるのは、 を使用して整数ベースの「中心」を与えるために丸めが発生したことに起因しているようですmapToScene(viewport()->rect().center());
。
これを回避する方法はありますか?浮動小数点の中心点を取得する方法がわかりません。
更新 3:
だから私はこれをほとんど解決しました.mapToSceneが必要であることがわかりました(ウェブ上の他の場所で見つけたコード)。
ビューポートの FP 計算された中心を保存することでこれを修正しました。これQPointF
で、2 つのビューをスクロールするときのエラーの量は目立たなくなりました。
最後の問題は、右にいくらかスクロールし、ウィンドウのサイズを変更してから再度スクロールすると、ビューが整列しなくなることです。これは、中心点が計算されたときとセンタリングが行われたときの論理的な順序付けと関係があると思います。
QGraphicsScene::ResizeEvent()
現在、必要に応じてセンターを更新する次のコードスニペットを使用しています。
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();
}
ウィンドウのサイズを変更すると、2 つのビューの配置が崩れる問題を修正するにはどうすればよいですか? さらに明確にする必要がある場合は、お尋ねください.
更新 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();
}
クラス 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);
}
}
クラス MainWindow のどこか:
connect(eventView, SIGNAL(horizontalScroll(int)), headerView, SLOT(horizontalScroll(int));