C++ 是否从QGraphicscene中删除QGraphicsSitem/QGraphicsObject?

C++ 是否从QGraphicscene中删除QGraphicsSitem/QGraphicsObject?,c++,qt,qgraphicsitem,qgraphicsscene,C++,Qt,Qgraphicsitem,Qgraphicsscene,我已经创建了QtGUI应用程序。它由QGraphicscene组成,QGraphicsSitems项通过按下或触发按钮添加到其中。添加到场景中的每个项目都是从QGraphicsItem派生的不同类的成员。现在,我的挑战是通过以下机制之一从场景中删除添加的项目: void QWidget::keyPressEvent( QKeyEvent *k ){ switch ( tolower(k->ascii()) ) { case '\x08': \\ba

我已经创建了QtGUI应用程序。它由QGraphicscene组成,QGraphicsSitems项通过按下或触发按钮添加到其中。添加到场景中的每个项目都是从QGraphicsItem派生的不同类的成员。现在,我的挑战是通过以下机制之一从场景中删除添加的项目:

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
1右键单击添加的项目,创建关联菜单,然后使用 场景->删除添加项

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
2双击删除该项目的项目

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
3使用ItemIsSelectable标志选择一个项目,然后按键盘上的delete键删除该项目

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
但话说回来,作为Qt的新手,我无法做到第一点,因为右键单击时上下文菜单不会显示。在第2个示例中,我使用了信号和插槽,每当双击一个项目时都会发出一个信号,主窗口中的插槽会吸收信号并删除该项目。但通过这种方式,程序无法编译,因为在向项类的头文件添加Q_对象宏时发现了错误重复符号

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
因此,我的最后一个选择是在屏幕上选择一个项目,然后按delete键,通过键盘信号删除该项目。如何做到这一点?请给我建议,如果上述任何方法可以很容易地做到,以防我可能会做得完全错误

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }

注:我知道有很多关于从QGraphicscene中删除QGraphicsItem的问题,但没有一个是可靠的答案。

你在寻找很多答案,而不是如何处理QGraphicsItem或QGraphicscene

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
1右键单击添加的项目,创建关联菜单,然后使用场景->RemoveItemAddItem

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
2双击该项目,这将删除该项目-您需要处理双击并点击测试QGraphicsItem,您必须实现mouseDoubleClickEventQMouseEvent*e并传递e的pos以确定是否单击了QGraphicsItem

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
3使用ItemIsSelectable标志选择一个项目,然后按键盘上的delete键删除该项目-我不确定ItemIsSelectable标志。但是,您需要2个。要了解如何处理键盘输入,请覆盖以下内容:

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
还有Qt::key枚举,它有key_Backspace和key_Delete。如果您不喜欢处理ASCII字符代码,可以针对QKeyEvent::Key的返回进行测试

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
。。。我不能做第一件事,因为右键单击时上下文菜单不显示

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
有两种可能的方法来实现这一点:

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
创建基于QWidget的菜单,附加到QGraphicsView。 创建您自己的菜单项,从QGraphicsItem派生。 虽然第二种方法需要更多的时间,但在我看来,它可能是一个更好的系统,因为它会感觉到与场景中要删除的项目更为整合。第一种方法也是可能的,如果它不起作用,那么你可以发布一个示例问题

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
2,我使用了信号和插槽。。。由于向头文件中添加Q_对象宏时发现的错误重复符号

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
听起来好像您正试图将信号/插槽功能添加到从QGraphicsItem派生的类中。你不需要这样做。Qt提供了一个类,如果您希望在QGraphicscene中的项目上有信号和插槽,则可以从该类派生,而不是从QGraphicsItem派生

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
按delete键,输入键盘信号以删除项目

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
我想你的意思是“传播”键盘信号。通过覆盖QGraphicscene及其keyPressEvent或keyReleaseEvent,可以获得选定项目的列表并将其从场景中删除。下面是一个骨架示例:-

void QWidget::keyPressEvent( QKeyEvent *k ){
     switch ( tolower(k->ascii()) ) {
         case '\x08':        \\backspace                       

             break;
         case '\x7F':         \\delete

             break;
     }
 }
class MyScene : public QGraphicsScene
{
    protected:
        void keyReleaseEvent(QKeyEvent * keyEvent);
};

void MyScene::keyReleaseEvent(QKeyEvent * keyEvent)
{
    if(keyEvent->key() == Qt::Key_Backspace)
    {
        QList<QGraphicsItem*> selectedItems = selectedItems(); // get list of selected items
        foreach(QGraphicsItem* item, selectedItems)
        {
            removeItem(item);
            delete item;
        }
    }
}

@乔纳森非常感谢你花时间回答我的问题。在您的回答中,我如何获得addedItem或selectedItem以将其传递给QGraphicscene::removeItem?谢谢你谢谢你回答黑暗骑士。您能详细说明一下我是如何将selectedItem的参数传递给qgraphicscene::removietem的吗?ThanksselectedItems返回项目列表。正如答案中的代码所示,您遍历项目列表并逐个删除它们。