1

我有一个加载图像的 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;
}

它希望它能够工作,但事实并非如此。

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

4

2 回答 2

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

于 2013-08-24T09:53:07.520 回答
2

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

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

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

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

  • 如果用户按下“UNDO”,则从 listUndo 堆栈中弹出最后完成的操作,撤消该操作并将该操作压入 listRedo 堆栈。

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

当然,正如我所说,上述内容似乎有点棘手且容易出错,因此最好使用 Qt Undo Framework 的内置功能。

于 2013-08-24T12:10:03.537 回答