在QgraphicsScene上逐个撤消或删除行

时间:2013-08-24 09:43:34

标签: qt undo qgraphicsscene

我有一个加载图像的QGraphicsView子类。然后,用户可以通过单击并拖动在该图像上绘制一些线条。

void TabView::mousePressEvent(QMouseEvent *event){
    if (event->button() == Qt::LeftButton) {
        scene->addLine(line);
    }
}

我添加了撤消功能,如下所示:

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

但这不起作用。我试过这个

case Qt::Key_Delete:
    QGraphicsLineItem *item = new QGraphicsLineItem(lineList.last());
    scene->removeItem(item);
    scene->update();
    break;

但这也行不通。

我的问题是:如何在QgraphicsScene中逐个撤消或删除项目?

修改 看看这个:

case Qt::Key_Delete:
{
    itemList = scene->items();
    itemList.removeLast();
    foreach(QGraphicsItem *item, itemList){
        scene->addItem(item);                   
    }
    scene->update();
    break;
}

它希望它起作用,但事实并非如此。

我真的想知道为什么它不起作用?

2 个答案:

答案 0 :(得分:3)

在删除代码中:

case Qt::Key_Delete:
    QGraphicsLineItem *item = new QGraphicsLineItem(lineList.last());
    scene->removeItem(item);
    scene->update();
    break;

您正在创建一个新的QGraphicsLineItem对象。该对象在场景中不存在,因此执行scene->removeItem(item)将不执行任何操作。

您需要跟踪添加到场景中的所有QGraphicsLineItem个对象,而不是用于创建它们的QLineF个对象。

您是否考虑过使用Qt Undo Framework

答案 1 :(得分:2)

如前所述,Qt Undo Framework最适合您。

但是,如果要实现自己的UNDO / REDO功能,则必须维护撤消和重做操作的堆栈列表。

例如,您可以拥有一个名为listUndo的堆栈和一个名为listRedo的堆栈。

  • 对于每次添加行或用户执行的任何其他操作,请按listUndo堆栈上的操作。另外,请记住在用户的每次操作中清除listRedo堆栈。

  • 如果用户按下“UNDO”,则弹出listUndo堆栈中的最后一个操作,撤消该操作并在listRedo堆栈上推送该操作。

  • 如果用户按下“REDO”,则弹出listRedo堆栈中撤消的最后一个操作,重做该操作并在listUndo堆栈上推送该操作。

正如我所说的那样,上面看起来有点棘手且容易出错,所以最好使用Qt Undo Framework的内置功能。<​​/ p>