2015-09-22 1 views
0

Je veux peindre en quelque sorte un rectangle de sélection sur scène, pour afficher les éléments sélectionnés (non il point rectangle de délimitation, mais le rectangle de délimitation mappé sur scène - et si la sélection multiple , le rectangle de délimitation de la sélection).membre QGraphicsRectItem d'une classe de scène personnalisée ajoutée sur l'action de la souris donne l'erreur

Je voudrais essayer quelque chose comme, sur la presse de la souris pour afficher le rectangle (et mise à jour basée sur la sélection en cours), et sur la libération de la souris, pour le cacher.

J'ai du mal à garder le rectangle sur la scène, et sur la libération de la souris, il peut être retirer, ou peut-être qu'il n'a jamais été là - et je reçois une erreur:

QGraphicsScene::removeItem: item 0x37828's scene (0x0) is different from this scene (0x1f57b68) 

(L'erreur ci-dessus, et le fait que l'objet ne reste pas après la pression de la souris, me fait penser qu'il n'est pas ajouté correctement mais je ne comprends pas pourquoi).

Voici un petit code exemple:

#include <QApplication> 
#include <QGraphicsView> 
#include <QGraphicsScene> 
#include <QGraphicsRectItem> 

class MyScene : public QGraphicsScene 
{ 
public: 
    MyScene(qreal x, qreal y, qreal w, qreal h) { 
     setSceneRect(x, y, w, h); 
     m_selectionRectangle = new QGraphicsRectItem(0,0,1,1); 
     m_selectionRectangle->setBrush(Qt::magenta); 
     m_selectionRectangle->setOpacity(0.2); 
    } 
    ~MyScene() { 
     if(m_selectionRectangle) 
      delete m_selectionRectangle; 
    } 
protected: 
    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) { 
     QGraphicsScene::mousePressEvent(event); 
     if(!selectedItems().isEmpty()) { 
      QRectF selectionRect = QRectF(); 
      foreach(QGraphicsItem* item, selectedItems()) 
       selectionRect |= item->mapToScene(item->boundingRect()).boundingRect(); 
      m_selectionRectangle->setRect(selectionRect); 
      addItem(m_selectionRectangle); 
     } 
    } 
    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { 
     QGraphicsScene::mouseReleaseEvent(event); 
     removeItem(m_selectionRectangle); 
    } 
private: 
    QGraphicsRectItem* m_selectionRectangle; 
}; 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 
    MyScene* s = new MyScene(0, 0, 800, 600); 
    QGraphicsView view(s); 
    view.setDragMode(QGraphicsView::RubberBandDrag); 
    view.show(); 
    QGraphicsRectItem* xxx = new QGraphicsRectItem(200, 200, 100, 100); 
    QGraphicsEllipseItem* yyy = new QGraphicsEllipseItem(300, 300, 200, 100); 
    s->addItem(xxx); 
    s->addItem(yyy); 
    xxx->setFlags(QGraphicsItem::ItemIsMovable|QGraphicsItem::ItemIsFocusable|QGraphicsItem::ItemIsSelectable); 
    yyy->setFlags(QGraphicsItem::ItemIsMovable|QGraphicsItem::ItemIsFocusable|QGraphicsItem::ItemIsSelectable); 
    return app.exec(); 
} 

Quelle est la signification de cette erreur, ce que je fais mal à ajouter le rectangle de sélection, et pourquoi ne pas y rester - et comment puis-je répare le ?

Répondre

0

La signification de l'erreur est littérale: vous passez un élément à removeItem qui n'est pas un élément enfant de la scène à laquelle vous tentez de le retirer. Il est absurde de supprimer un élément qui n'est pas dans la scène pour commencer.

Rien ne garantit que le rectangle de sélection est sur la scène lorsque le bouton de la souris est relâché, car il y a des chemins à travers mousePressEvent qui n'ajoutent pas le rectangle à la scène. Je ne suis même pas sûr si vous êtes assuré d'avoir un événement de presse précédant chaque événement de sortie du tout.

Vous devez seulement supprimer le rectangle si elle est sur la scène (et virtual n'est pas nécessaire, mais Q_DECL_OVERRIDE est!):

void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE { 
    QGraphicsScene::mouseReleaseEvent(event); 
    if (m_selectionRectangle.scene()) removeItem(m_selectionRectangle); 
} 

En outre, le destructeur de votre scène personnalisée est inutile. Il suffit d'ajouter l'article par la valeur:

class MyScene : public QGraphicsScene 
{ 
    QGraphicsRectItem m_selectionRectangle; 
public: 
    MyScene(qreal x, qreal y, qreal w, qreal h) : 
     m_selectionRectangle(0, 0, 1 1) 
    { 
     setSceneRect(x, y, w, h); 
     m_selectionRectangle.setBrush(Qt::magenta); 
     m_selectionRectangle.setOpacity(0.2); 
    } 
protected: 
    void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE { 
     ... 
    } 
    ... 
};