QT QGrapicsSene und QRubberBand

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

QT QGrapicsSene und QRubberBand

Beitrag von abcmann74 »

Hallo

ich möchte gerne ein rechteck in meiner graphicscene ziehen und dann die daten aus dem Qrect rauslesen. außerdem will ich das mausrad benutzen. ich habe folgenden code geschrieben, den der compiler ohne meckern annimmt. wenn ich die datei jedoch starte, und ich in der graphic scene klicke bzw. eine rechteck ziehen will, passiert gar nichts.

Code: Alles auswählen

void MainWindow::wheelEvent(QGraphicsSceneWheelEvent* event)
{
	
	if(event->delta()<=0)
  {
    ZoomOut();
  }
  else
  {
    ZoomIn();
  }
}

void MainWindow::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
	
	P_ = event->scenePos();
	
  if (!RubberBand_)
    RubberBand_ = new QRubberBand(QRubberBand::Rectangle, this);
		RubberBand_->setGeometry(QRect(P_.toPoint(), QSize()));
  RubberBand_->show();

  cout<<"mouse";
}

void MainWindow::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{

	F_=event->scenePos();
	RubberBand_->setGeometry(QRect(P_.toPoint(), F_.toPoint()));
}

void MainWindow::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
	
	RubberBand_->hide();
  // determine selection, for example using QRect::intersects()
  // and QRect::contains().
}

kann mir da vllt. jemand weiterhelfen?
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Code: Alles auswählen

  if (!RubberBand_) 
     RubberBand_ = new QRubberBand(QRubberBand::Rectangle, this); 
       RubberBand_->setGeometry(QRect(P_.toPoint(), QSize())); 
1. Das ist nicht lesbar.
2. Was sagt der Debugger dazu?
abcmann74
Beiträge: 31
Registriert: 3. Mai 2010 11:03

Beitrag von abcmann74 »

hi upsala

danke für deine antwort. Ich habe die if Anweisung mal weggelassen und es funktioniert. Außerdem habe ich normale MouseEvents verwendet und keine SceneMouse Events.

Jetzt habe ich jedoch das Problem, dass ich nicht weiß wie ich das ganze in meine Graphic Scene bekomme. In meinem MainWindow klappt das alles aber wie kann ich die Events in meinem GrpahicScene Fenster abfangen?

Hier nochmal der neue Code:

Code: Alles auswählen

void MainWindow::wheelEvent(QWheelEvent* event)
{
  if(event->delta()<=0)
  {
    ZoomOut();
    cout<<"out"<<endl;
  }
  else
  {
    ZoomIn();
    cout<<"in"<<endl;
  }
}

void MainWindow::mousePressEvent(QMouseEvent* event)
{
  P_ = event->pos();

  xPos->setText(QString().setNum(P_.x()));
  yPos->setText(QString().setNum(P_.y()));

  RubberBand_ = new QRubberBand(QRubberBand::Rectangle, this);
	
  RubberBand_->setGeometry(QRect(P_, QSize(0,0)));
  RubberBand_->show();
}

void MainWindow::mouseMoveEvent(QMouseEvent* event)
{
  F_=event->pos();
  RubberBand_->setGeometry(QRect(P_, F_).normalized());
}

void MainWindow::mouseReleaseEvent(QMouseEvent* event)
{
	RubberBand_->hide();
  // determine selection, for example using QRect::intersects()
  // and QRect::contains().
}
abcmann74
Beiträge: 31
Registriert: 3. Mai 2010 11:03

Beitrag von abcmann74 »

hi
ich habe es jetzt mal so versucht. es funktioniert leider nicht.

Code: Alles auswählen

void ImageWindow::wheelEvent(QGraphicsSceneWheelEvent* event)
{
  if(event->delta()<=0)
  {
    ZoomOut();
  }
  else
  {
    ZoomIn();
  }
  wheelEvent(event);
}

void ImageWindow::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
  P_ = event->scenePos();
  cout<<"x"<<P_.x()<<endl;
  cout<<"y"<<P_.y()<<endl;
  RubberBand_->setGeometry(QRect(P_.toPoint(), QSize(0,0)));
  RubberBand_->show();
  
  mousePressEvent(event);
} 

void ImageWindow::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{    
  

  F_ = event->scenePos();

  RubberBand_->setGeometry(QRect(P_.toPoint(), F_.toPoint()).normalized());   
   
  mouseMoveEvent(event);
  
}

void ImageWindow::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
  RubberBand_->hide();

  Rect_ = QRect(P_.toPoint(), F_.toPoint()).normalized();

  cout<<"Breite"<<Rect_.width()<<endl;
  cout<<"Höhe"<<Rect_.height()<<endl;
  
  mouseReleaseEvent(event);

}
die Events werden irgendwie nicht registriert...

grüße
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Wenn du eh schon mit dem Graphics View Framework arbeitest, leite doch gleich von QGraphicsView/Scene ab (scene ist vllt. etwas leichter, wenn deine scene in mehreren Views angezeigt werden soll und das Auswahlrechteck nur dort sichbar sein soll, musst du von der view ableiten).
Wenn du von der Scene ableitest kannst du einfach statt nem QRubberBand ein QGraphicsRectItem einblenden. Sollte (wg. Umrechnung scenecoordinates<->viewcoordinates) leichter sein an die Items im rect zu kommen.

BTW: wenn ImageWindow ein normales QWidget (im Prinzip alles andere außer QGraphicsScene) ist, wirst du mit diesen events nicht weit kommen. QGraphicsSceneMouseEvents bekommst du nur (!) in ner QGraphicsScene! Wenn du mit einer Basisklasse !QGraphicsScene arbeitest, musst du die normalen Events überschreiben.
abcmann74
Beiträge: 31
Registriert: 3. Mai 2010 11:03

Beitrag von abcmann74 »

danke franzf. hat funtioniert.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Bittebitte ;)
Du könntest auch noch schreiben, wie du es gelöst hast (nur kurzen Abriss), falls jemand wieder das Problem haben sollte.
abcmann74
Beiträge: 31
Registriert: 3. Mai 2010 11:03

Beitrag von abcmann74 »

hi

Also im Endeffekt hab ich das ganze folgend gelöst. Ich habe heute zufällig in der Dokumentation gelesen, dass es in der QGraphicsView Klasse eine DragMode Funktion gibt. Mit dieser kann man direkt ein Rubberband erstellen oder per gedrückter Maustaste das "Viewfenster" verschieben. Ich habe das ganze so gecodet, dass ich per Leertaste zwischen den beiden Modis hin und her switchen kann. Die gewünschten Koordianten schreibe ich in ein QRect, aus dem ich später auslesen kann.
Hier mal der Code:

Code: Alles auswählen

void ImageWindow::wheelEvent(QGraphicsSceneWheelEvent* event )
{
  if(event->delta()<0)
  {
    ZoomOut();
  }
  else
  {
    ZoomIn();
  }
}

void ImageWindow::mousePressEvent(QGraphicsSceneMouseEvent* event)
{	
  P_ = event->scenePos();
} 

void ImageWindow::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
  F_=event->scenePos();
  Rect_ = QRectF(P_, F_);

  cout<<"Breite"<<Rect_.width()<<endl;
  cout<<"Höhe"<<Rect_.height()<<endl;
	cout<<"P x"<<P_.x()<<endl;
  cout<<"P y"<<P_.y()<<endl;
	cout<<"F x"<<F_.x()<<endl;
  cout<<"F y"<<F_.y()<<endl;

	Contrast(20);
}

void ImageWindow::keyPressEvent(QKeyEvent* event)
{
  if(event->key()==Qt::Key_Space && B_==false)
  {
    View_->setDragMode(QGraphicsView::ScrollHandDrag);
    B_ = true;
  }
  else
  {
    View_->setDragMode(QGraphicsView::RubberBandDrag);
    B_ = false;
  }
}
Das Problem mit den QGraphicsScene Events habe ich mit einer eigenen abgeleiteten QGraphicsScene Klasse realisiert.
Hoffe das hilft jemanden irgendwie weiter :-):
Antworten