1
votes

I have created Qt GUI application. It consists of QGraphicsScene, and items (QGraphicsItems) are added to them by pressing or triggering pushbuttons. Each item added to the scene are members of different classes derived from QGraphicsItem. Now, my challenge is to delete an added item off the scene through one of the following mechanisms:

1) Right click an added item, create a context menu, and then use scene->removeItem(addedItem);

2) Double click the item which deletes the item

3) Select an item using the flag ItemIsSelectable, and then delete the item by pressing the delete key on the keyboard

But having said that, as a newbie to Qt, I'm unable to do number 1 since the context menu doesn't show up when right clicked. In the case of number 2, I used signals and slots, a single emitted whenever an item is double clicked, and a slot in the mainWindow absorbs the signal and removes the item. But this way, the programs fails to compile because of the error "duplicate symbol found" when I add a Q_OBJECT macro to the header file of the item's class.

So my final option is to select an item on the screen and propane the keyboard signal to delete the item by pressing delete. How can be this done? Please give me advice if any of the above methods can be easily done in case I might be doing it completely wrong.

P.S. : I know there a lot of queries regarding deleting QGraphicsItem off QGraphicsScene, but none of them document a solid answer.

2

2 Answers

1
votes

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

There are two possible methods to accomplish this:

  1. Create a QWidget based menu, attached to the QGraphicsView.
  2. Create your own menu item, derived from a QGraphicsItem.

Whilst the 2nd method will take more time, it's probably a better system in my opinion, as it will feel more integrated with the item you're deleting in the scene. The first method is also possible and if it's not working, then you could post an example question on 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

It sounds like you're trying to add the signal / slot functionality to a class derived from QGraphicsItem. You don't need to do this. Qt provides the QGraphicsObject class, which you can derive from, instead of QGraphicsItem, if you want signals and slots on items in a QGraphicsScene.

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

I assume you mean to 'propagate' keyboard signals. By overriding the QGraphicsScene and its keyPressEvent or keyReleaseEvent, you can get a list of selected items and delete them from the scene. Here's a skeleton example: -

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

You're seeking a lot of answers, Not so much how to handle QGraphicsItem or QGraphicsScene.

1) Right click an added item, create a context menu, and then use scene->removeItem(addedItem); here.

2) Double click the item, which deletes the item - you'll need to handle double clicks, and hit-testing the QGraphicsItems, you'll have to implement mouseDoubleClickEvent(QMouseEvent *e) and pass e's pos() to this to determine if a QGraphicsItem was clicked or not.

3) Select an item using the flag ItemIsSelectable and then delete the item by pressing the delete key on the keyboard - I'm not sure about the ItemIsSelectable flag. However, you'll need #2. And to learn how to handle keyboard input, by overriding this:

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

             break;
         case '\x7F':         \\delete

             break;
     }
 }

There's also the Qt::key enumeration, which has Key_Backspace, and Key_Delete. It can be tested against the QKeyEvent::Key()'s return if you don't like dealing with ASCII character codes.