2013-08-26 1 views
2

J'ai un QGraphicsView et un QGraphicsScene. Selon l'entrée de l'utilisateur, certains QGraphicsItem peuvent être placés sur la scène. Cet article est à la fois sélectionnable et mobile.Création d'une fonction de défilement automatique dans QGraphicsView

Lorsque la scène est plus grande que la vue, les barres de défilement s'affichent (elles sont définies pour s'afficher si nécessaire).

Lorsque l'article est déplacé par l'utilisateur près du bord de la vue la largeur scène/hauteur sont étirées en conséquence - je fais plus la scène.

La question est comment forcer les barres de défilement à défiler avec la scène lorsque l'élément est proche de la bordure de la vue? Fonctionnalité Je pense que commun dans n'importe quel éditeur graphique. Dans le MouseMoveEvent de la scène, je rends la scène plus grande, force les curseurs à se déplacer et à mettre à jour le rectangle visible en conséquence.

Cela ne fonctionne pas comme prévu. Même si les parchemins s'adaptent à la nouvelle taille de la scène, il n'y a pas de mouvement régulier dans la vue. Y a-t-il une meilleure façon de faire cela?

Quelques explications:

itemUnderCursor = currently slected QGraphicsItem 
    qgv = QGraphicsView 

extrait de code:

// check if item is near the border 
    QPointF point = itemUnderCursor->mapToScene(itemUnderCursor->boundingRect().topLeft()); 
    double delta = 0; 

    if(point.x() < visibleRect.left()) 
    { 
     // prevent from drawing outside the scene 
     itemUnderCursor->setPos(visibleRect.left(), itemUnderCursor->scenePos().y()); 

     if(event->scenePos().x() < oldMousePos.x()-3) 
     { 
      // stretch the scene 
      if(qgv->horizontalScrollBar()->value() <= 0) 
       setSceneRect(QRectF(QPointF(sceneRect().x() - 3, sceneRect().y()), sceneRect().bottomRight())); 
      /* 
      * disable signals from DrawingArea in order to avoid 
      * recursive calls of mouseMoveEvent then enabling them 
      * back to handle the rest of events 
      */ 
      this->blockSignals(true); 
      delta = point.x() - originalRect.left(); 
      qgv->horizontalScrollBar()->setValue(hScrollOriginalValue + delta); 
     } 
     oldMousePos = event->scenePos(); 
     this->blockSignals(false); 

     // update the visible rectangle 
     visibleRect = getVisibleRect(qgv); 
    } 

    if(point.x() + itemUnderCursor->boundingRect().width() > visibleRect.right()) 
    { 
     // prevent from drawing outside the scene 
     itemUnderCursor->setPos(visibleRect.right() - itemUnderCursor->boundingRect().width(), itemUnderCursor->scenePos().y()); 
     if(event->scenePos().x() > oldMousePos.x()+3) 
     { 
      // stretch the scene 
      if(qgv->horizontalScrollBar()->value() >= 0) 
       setSceneRect(QRectF(sceneRect().topLeft(), QPointF(sceneRect().bottomRight().x() + 3, sceneRect().bottomRight().y()))); 

      /* 
      * disable signals from DrawingArea in order to avoid 
      * recursive calls of mouseMoveEvent then enabling them 
      * back to handle the rest of events 
      */ 
      delta = point.x() + itemUnderCursor->boundingRect().width() - originalRect.right(); 
      this->blockSignals(true); 
      qgv->horizontalScrollBar()->setValue(hScrollOriginalValue + delta); 
     } 
     oldMousePos = event->scenePos(); 
     this->blockSignals(false); 

     // update the visible rectangle 
     visibleRect = getVisibleRect(qgv); 
    } 

Je suis en train de faire la même chose pour la bordure supérieure et inférieure du QGraphicsView.

+2

Utilisez la fonction centerOn dans QGraphicsView pour placer la fenêtre sur une zone particulière http://harmattan-dev.nokia.com/docs/platform-api-reference/xml/daily-docs/libqt4/qgraphicsview.html#centerOn- 2 – Wagmare

+0

@Wagmare ne centerOn() placer l'élément exactement au centre de la vue? Je aurais besoin de fournir un certain point par rapport à l'élément afin de maintenir l'élément lui-même près de la frontière, à droite? –

Répondre

6

Il semble que ma précédente tentative était terriblement compliquée alors que la solution est en fait très facile.

au lieu du code précédent, il suffisait d'écrire:

qgv->ensureVisible(itemUnderCursor); 

et assurez-vous que sceneRect() ne sera pas réglé avec une valeur, mais reste à traiter par la scène elle-même.

Ceci a permis à la scène d'ajuster automatiquement sa taille en fonction des éléments qu'elle contient et a forcé les barres de défilement à suivre l'élément en mouvement à l'extérieur du rectangle visible de QGraphicsView.

Questions connexes