Reputation: 662
I have a QGraphicsView subclass that loads an image. Then, the user can draw some lines on that image by clicking and dragging.
void TabView::mousePressEvent(QMouseEvent *event){
if (event->button() == Qt::LeftButton) {
scene->addLine(line);
}
}
I added undo functionality, like this:
void TabView::mousePressEvent(QMouseEvent *event){
if (event->button() == Qt::LeftButton) {
lineList<<line;
scene->addLine(lineList.last());
}
}
void TabView::keyPressEvent(QKeyEvent * event){
int key = event->key();
switch(key){
case Qt::Key_Delete:
{
lineList.removeLast();
foreach(QLineF line, lineList){
scene->addLine(line);
}
scene->update();
break;
}
}
}
But this does not work. I have tried this
case Qt::Key_Delete:
QGraphicsLineItem *item = new QGraphicsLineItem(lineList.last());
scene->removeItem(item);
scene->update();
break;
but this also doesn't work.
My problem is: How can I undo or just delete items one by one in a QgraphicsScene?
EDIT: look at this:
case Qt::Key_Delete:
{
itemList = scene->items();
itemList.removeLast();
foreach(QGraphicsItem *item, itemList){
scene->addItem(item);
}
scene->update();
break;
}
It expected it to work, but it isn't.
I am really wondering why it doesn't work?
Upvotes: 1
Views: 1744
Reputation: 12705
As already suggested, Qt Undo Framework shall be best suited to you.
However, if you want to implement your own UNDO / REDO functionality, then you will have to maintain stack lists of the operations for undo and redo.
For example, you can have a stack called listUndo and a stack called listRedo.
For every addition of line or any other operation conducted by the user, push the operation on the listUndo stack. Also, remember to clear the listRedo stack on every operation by the user.
If the user presses "UNDO", then pop out the last operation done from the listUndo stack, undo that operation and push that operation on the listRedo stack.
If the user presses "REDO", then pop out the last operation undone from the listRedo stack, redo that operation and push that operation on the listUndo stack.
Ofcourse as I said, the above seems a bit tricky and bug-prone, so best would be to use a built in functionality of Qt Undo Framework.
Upvotes: 2
Reputation: 4360
In your deletion code:
case Qt::Key_Delete:
QGraphicsLineItem *item = new QGraphicsLineItem(lineList.last());
scene->removeItem(item);
scene->update();
break;
You are creating a new QGraphicsLineItem object. This object does not exist in the scene so executing scene->removeItem(item)
will do nothing.
You need to keep track of all the QGraphicsLineItem
objects that you add to the scene, not the QLineF
objects that you use to create them with.
Have you thought about using the Qt Undo Framework?
Upvotes: 3