QGraphicsView zeigt nicht die gesamte QGraphicsScene an

Alles rund um die Programmierung mit Qt
Antworten
abcmann74
Beiträge: 31
Registriert: 3. Mai 2010 11:03

QGraphicsView zeigt nicht die gesamte QGraphicsScene an

Beitrag von abcmann74 »

Hi

Ich habe eine QGraphicsScene Klasse implementiert, in der ich einen QGraphicsView erzeuge, welcher diese Scene anzeigt. Dem View übergebe ich als Parent ein QGraphicsView in meinem MainWindow. So kann ich meine Scene bequem in meinem MainWindow bearbeiten, Events abfangen usw.

Ich habe nun folgendes Problem. Der View zeigt komischerweise nur einen Teil meines SceneItems (Pixmap) an. Sobald ich rein zoome (den View über scale() transformiere) kann ich über meinen implementierten Drag Mode immer mehr von der Scene sehen. Irgendwann ist dann aber Schluß und ich kann mit im Dragmode nicht mehr weiter "draggen" obwohl das Bild eigentlich größer ist. Als ich die beiden Fenster (Main Window und QGraphicsScene) getrennt angezeigt habe, hat alles noch funktioniert. Hängt es vllt damit zusammen, dass der View aus dem QT Designer sich irgendwie von dem den ich meiner QGraphicsScene Klasse (ImageWindow) erstellt habe unterscheidet? Hier mal der Code.

MainWindow class:

Code: Alles auswählen

void MainWindow::Load(void)
{
	FilePath_ = QFileDialog::getOpenFileName(
    0,
    "Durchsuchen",
    "",
    "Images (*.*)",
    0,
    0);

  if (FilePath_.isEmpty())
    return;
  
  LoadedImage_ = QImage (FilePath_);
  ImageWindow_->Init(ViewMainWindow_); 
  ImageWindow_->ShowImage(LoadedImage_);
}
ViewMainWindow_ ist ein QgraphicsView, den ich mittels dem QT Designer meinem MainWindow hinzugefügt habe.

ImageWindow class:

Code: Alles auswählen

void ImageWindow::Init(QWidget* parent /* = 0 */)
{
  View_ = new QGraphicsView(parent);

  View_->setDragMode(QGraphicsView::RubberBandDrag);
  View_->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
}

void ImageWindow::ShowImage(QImage& image)
{
  if(image.isNull())
    return;

  QList<QGraphicsItem *> list = this->items();
  for (int i = 0; i < list.size(); i++)
  {
    removeItem(list[i]); 
    delete list[i];
  }

  //Kopie für Restore
  Temp_ = image; 

  //Add the Image to the QGraphicsScene
  addPixmap(QPixmap::fromImage(Temp_));

  //Set the Image to background/bottom layer (ZValue=0)
  QGraphicsItem *background = itemAt(0,0);
  background->setZValue(0);

  View_->setScene(this);
  /*View_->scale(0.5,0.5);*/
  View_->show();
}
Vllt. kann mir ja jemand helfen.

grüße
Himbeer-Toni
Beiträge: 11
Registriert: 7. Juni 2010 07:49

Beitrag von Himbeer-Toni »

Kann es sein dass deine Szene einfach zu klein ist?

QGraphicsScene:
void setSceneRect ( qreal x, qreal y, qreal w, qreal h )

Sollte der Größe der View entsprechen:
Scene.setSceneRect(0,0,View.width(),View.height())
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Oioioi, da ist noch einiges im Argen :P
Das grobe Prinzip schaut ja so aus:
Scene: hält die Items
View: rendert die scene.
Dabei kann eine Scene in vielen views (->QGraphicsScene::views() gibt sie dir alle) angezeigt werden, siehe auch die "Chips"-Demo.
Was du jetzt machst ist, einer scene genau eine view zu geben.
Ich habe eine QGraphicsScene Klasse implementiert, in der ich einen QGraphicsView erzeuge, welcher diese Scene anzeigt. Dem View übergebe ich als Parent ein QGraphicsView in meinem MainWindow. So kann ich meine Scene bequem in meinem MainWindow bearbeiten, Events abfangen usw.
Du hast also dein "View" in deiner Scene-Klasse, der View übergibst du ein weiteres QGraphicsView als parent?!? Du brauchst wie gesagt in scene kein view, deine view gehört NUR in die MainWindow. Deine scene befreist du bitte von der view, und setzt in MainWindow deine scene in die dort erstellte view. Ich denke, in dieser komischen Konstellation liegt das Problem.
Und um Events abzufangen, brauchst du nicht diese Misch-Kombi, das bringt nix. Wenn du von QGraphicsScene ableitest, kannst du dort die passenden events abfangen. Auf die Events der view könntest du eh nur in nem eventFilter reagieren, diesen kannst du genauso gut in deinem MainWindow implementieren.

@Himbeer-Toni:
setSceneRect() sollte man wirklich nur machen, wenn man genau weiß was man tut. Normalerweise wird das sceneRect über die Items, die in der scene liegnen, bestimmt. Setzt du EINMAL scene Rect, ist diese Größe statisch, liegen Items nicht mehr in dem rect, hast du ein Problem :P
Ein setSceneRect vergrößert (oder verkleinert) auch nicht die Items, sondern nur die scene, was im Endeffekt gar nix bringt. set SceneRect ist also eher eine unnötige Fehlerquelle, wenn man nicht genau aufpasst. (Hatten wir hier kürzlich ;))
Antworten