从 QGraphicsScene 中删除 QGraphicsItem/QGraphicsObject?
Deleting a QGraphicsItem/QGraphicsObject from QGraphicsScene?
我已经创建了 Qt GUI 应用程序。它由 QGraphicsScene
组成,通过按下或触发 pushbutton
s 可以向其中添加项目 (QGraphicsItem
s)。添加到场景中的每个项目都是来自 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.
有两种可能的方法可以实现此目的:
- 创建一个基于 QWidget 的菜单,附加到 QGraphicsView。
- 创建您自己的菜单项,派生自 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;
}
}
}
我已经创建了 Qt GUI 应用程序。它由 QGraphicsScene
组成,通过按下或触发 pushbutton
s 可以向其中添加项目 (QGraphicsItem
s)。添加到场景中的每个项目都是来自 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.
有两种可能的方法可以实现此目的:
- 创建一个基于 QWidget 的菜单,附加到 QGraphicsView。
- 创建您自己的菜单项,派生自 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;
}
}
}