从 QGraphicsScene 中删除 QGraphicsItem/QGraphicsObject?

Deleting a QGraphicsItem/QGraphicsObject from QGraphicsScene?

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

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

2) 双击删除项目的项目

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

但话虽如此,作为 Qt 的新手,我无法执行第 1 项,因为右键单击时上下文菜单不显示。在第 2 种情况下,我使用了信号和插槽,只要双击一个项目就会发出一个信号,mainWindow 中的一个插槽吸收信号并删除该项目。但是这样,当我在项目的class的头文件中添加Q_OBJECT宏时,由于错误"duplicate symbol found",程序无法编译。

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

P.S。 : 我知道有很多关于从 QGraphicsScene 中删除 QGraphicsItem 的问题,但其中 none 记录了可靠的答案。

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

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

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

3) Select 使用标志 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() 的 return 进行测试。

... I'm unable to do number 1 since the context menu doesn't show up when right clicked.

有两种可能的方法可以实现此目的:

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

虽然第二种方法会花费更多时间,但在我看来它可能是一个更好的系统,因为它会感觉与您在场景中删除的项目更加融合。第一种方法也是可行的,如果它不起作用,那么你可以 post 关于 SO 的示例问题。

2, I used signals and slots, ... because of the error "duplicate symbol found" when I add a Q_OBJECT macro to the header file

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

propane the keyboard signal to delete the item by pressing delete.

我假设你的意思是 'propagate' 键盘信号。通过覆盖 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;
        }
    }
}