Qt 在鼠标操作中添加的自定义场景类的QGraphicsRectItem成员出现错误

Qt 在鼠标操作中添加的自定义场景类的QGraphicsRectItem成员出现错误,qt,mouseevent,qgraphicsitem,qgraphicsscene,Qt,Mouseevent,Qgraphicsitem,Qgraphicsscene,我想以某种方式在场景上绘制一个选择矩形,以显示选定的项目(不是项目边界矩形,而是映射到场景的边界矩形,如果是多个选择,则显示选择边界矩形) 我想尝试一下,在鼠标按下时,显示矩形(并根据当前选择进行更新),在鼠标释放时,隐藏矩形 我在将矩形保留在场景中时遇到问题,在释放鼠标时,它可能会将其删除,或者它从未出现过-我得到一个错误: QGraphicsScene::removeItem: item 0x37828's scene (0x0) is different from this scene (

我想以某种方式在场景上绘制一个选择矩形,以显示选定的项目(不是项目边界矩形,而是映射到场景的边界矩形,如果是多个选择,则显示选择边界矩形)

我想尝试一下,在鼠标按下时,显示矩形(并根据当前选择进行更新),在鼠标释放时,隐藏矩形

我在将矩形保留在场景中时遇到问题,在释放鼠标时,它可能会将其删除,或者它从未出现过-我得到一个错误:

QGraphicsScene::removeItem: item 0x37828's scene (0x0) is different from this scene (0x1f57b68)
(上面的错误,加上鼠标按下后项目没有停留,使我认为它没有正确添加,但我不明白为什么)

下面是一个小示例代码:

#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();
}
#包括
#包括
#包括
#包括
类MyScene:publicqgraphicscene
{
公众:
MyScene(qreal x,qreal y,qreal w,qreal h){
(x,y,w,h);
m_selectionRectangle=新的QGraphicsRectItem(0,0,1,1);
m_选择矩形->退刀(Qt::洋红色);
m_选择矩形->设置不透明度(0.2);
}
~MyScene(){
如果(m_选择矩形)
删除m_选择矩形;
}
受保护的:
虚拟无效MousePresseEvent(QGraphicsSceneMouseEvent*事件){
qgraphicscene::mousePressEvent(事件);
如果(!selectedItems().isEmpty()){
QRectF selectionRect=QRectF();
foreach(QGraphicsItem*项,selectedItems())
selectionRect |=item->maptosene(item->boundingRect()).boundingRect();
m_selectionRectangle->setRect(selectionRect);
附加项(m_选择矩形);
}
}
虚拟无效mouseReleaseEvent(QGraphicsSceneMouseEvent*事件){
QGraphicscene::mouseReleaseEvent(事件);
removeItem(m_Selection长方形);
}
私人:
QGraphicsRectItem*m_选择矩形;
};
int main(int argc,char*argv[])
{
QApplication应用程序(argc、argv);
MyScene*s=新的MyScene(0,0,800600);
QGraphicsView视图;
view.setDragMode(QGraphicsView::RubberBandDrag);
view.show();
QGraphicsRecitem*xxx=新的QGraphicsRecitem(200200100100);
QGraphicsEllipseItem*yyy=新的QGraphicsEllipseItem(300300200100);
s->addItem(xxx);
s->addItem(yyy);
xxx->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::itemisselect);
yyy->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsSelectable);
返回app.exec();
}

该错误的含义是什么,我在添加选择矩形时做错了什么,为什么它不留在那里?我如何修复它?

错误的含义是字面意义:您将一个项目传递给
removietem
,而该项目不是您试图从中删除的场景的子项目。删除不在场景中的项目是毫无意义的

没有任何东西可以保证释放鼠标按钮时选择矩形在场景中,因为通过
mousePressEvent
的路径不会将矩形添加到场景中。我甚至不确定你是否保证在每次发布活动之前都会得到一次新闻发布会

仅当矩形在场景中时才需要删除它(不需要
virtual
,但
Q\u DECL\u OVERRIDE
是!):

此外,自定义场景的析构函数是不必要的。只需按值添加项目:

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 {
        ...
    }
    ...
};
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 {
        ...
    }
    ...
};