【问题标题】:Deleting a QGraphicsItem/QGraphicsObject from QGraphicsScene?从 QGraphicsScene 中删除 QGraphicsItem/QGraphicsObject?
【发布时间】:2015-11-01 13:12:50
【问题描述】:

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

1) 右键单击​​添加的项目,创建上下文菜单,然后使用 scene->removeItem(addedItem);

2) 双击删除项目的项目

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

但是话虽如此,作为 Qt 的新手,我无法做到第 1 点,因为右键单击时不会显示上下文菜单。在数字 2 的情况下,我使用了信号和槽,每当双击一个项目时发出一个信号,mainWindow 中的一个槽吸收信号并删除该项目。但是这样,当我在项目类的头文件中添加Q_OBJECT 宏时,由于“发现重复符号”错误,程序无法编译。

所以我的最后一个选择是在屏幕上选择一个项目,然后通过按删除键发出键盘信号以删除该项目。怎么可能做到这一点?如果上述任何方法都可以轻松完成,请给我建议,以防我做错了。

附: : 我知道有很多关于删除 QGraphicsItemQGraphicsScene 的问题,但没有一个是可靠的答案。

【问题讨论】:

    标签: c++ qt qgraphicsitem qgraphicsscene


    【解决方案1】:

    ...我无法执行第 1 项,因为右键单击时上下文菜单不显示。

    有两种可能的方法可以做到这一点:

    1. 创建一个基于 QWidget 的菜单,附加到 QGraphicsView。
    2. 创建您自己的菜单项,从 QGraphicsItem 派生。

    虽然第二种方法会花费更多时间,但我认为它可能是一个更好的系统,因为它会感觉与您在场景中删除的项目更加集成。第一种方法也是可能的,如果它不起作用,那么您可以在 SO 上发布一个示例问题。

    2,我使用了信号和插槽,...因为我在头文件中添加Q_OBJECT宏时出现错误“发现重复符号”

    听起来您正在尝试将信号/插槽功能添加到从 QGraphicsItem 派生的类中。你不需要这样做。 Qt 提供了QGraphicsObject 类,如果您想要 QGraphicsScene 中的项目上的信号和槽,您可以从该类派生而不是 QGraphicsItem。

    通过按下删除键来发出键盘信号以删除项目。

    我假设您的意思是“传播”键盘信号。通过覆盖 QGraphicsScene 及其 keyPressEvent 或 keyReleaseEvent,您可以获得所选项目的列表并将它们从场景中删除。这是一个骨架示例:-

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

    【讨论】:

    • 感谢您回答@TheDarkKnight。您能否详细说明我如何获得“selectedItem”的参数以将其传递给 QGraphicsScene::removeItem()?谢谢
    • selectedItems() 返回项目列表。正如答案中的代码所示,您遍历项目列表并将它们一一删除。
    【解决方案2】:

    您正在寻找很多答案,而不是如何处理 QGraphicsItem 或 QGraphicsScene。

    1) 右键单击​​添加的项目,创建上下文菜单,然后使用scene-&gt;removeItem(addedItem); here

    2) 双击该项目,这将删除该项目 - 您需要处理双击并命中测试 QGraphicsItems,您必须实现 mouseDoubleClickEvent(QMouseEvent *e) 并将 e 的 pos() 传递给 this确定是否点击了 QGraphicsItem。

    3) 使用标志ItemIsSelectable 选择一个项目,然后按键盘上的删除键删除该项目 - 我不确定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() 的返回进行测试。

    【讨论】:

    • @Jonathan 非常感谢您抽出宝贵时间回答我的问题。在 1) 中,我如何让“addedItem”或“selectedItem”将其传递给 QGraphicsScene::removeItem()?谢谢
    猜你喜欢
    • 2011-11-17
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多