How to erase a QGraphicsItem from QGraphicsView using QPushButton

旧城冷巷雨未停 提交于 2019-12-10 11:58:49

问题


I am building a major user interface but I am stuck on a problem and in order to shrink the problem I build a small working example that carries exactly the problem.

After the user creates a new .db file using the icon and saving for example to Desktop it is possible to load images(only in .png format for now) in the QGraphicsView and cliking on the checkbox to enable from Right: Drag to Right:Select it is possible to draw boxes on the image. With a right click inside the drawn box we can open a QDialog that asks to name the extracted image from the box. The image is stored in the QTableView as shown in the small working example below:

The problem: I tried several ways to erase the box (and the related index on the QTableView of the related box) but none of them was successful. With the use of the "Erase Square" QPushButton I am trying to erase the box. Every box can be re-activated by just left double-clicking within the interested box. See below what I am trying to achieve:

I draw the box on the QGraphicsView and right mouse click to capture the image from the box:

void MainWindow::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if(event->button() == Qt::RightButton)
      {
        this->setContextMenuPolicy(Qt::CustomContextMenu);
        connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
                this, SLOT(ShowContextMenu(const QPoint &)));
      }
}

void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
    Q_UNUSED(event);
    leftScene->clearSelection();     // Selections would also render to the file
    leftScene->setSceneRect(leftScene->itemsBoundingRect());    // Re-shrink the scene to it's bounding contents
    QImage image(leftScene->sceneRect().size().toSize(), QImage::Format_ARGB32);  // Create the image with the exact size of the shrunk scene
    image.fill(Qt::transparent);     // Start all pixels transparent

    QPainter painter(&image);
    leftScene->render(&painter);
    QImage subimage = image.copy(QRect(start.toPoint(), end.toPoint()));

    clipSceneDialog d(this);
    d.show();
    d.setImage(subimage);
    d.setHeaderImage(currentLeftImagePath);
    d.setBoundingBox(QRect(start.toPoint(), end.toPoint()));

    if(d.exec() == QDialog::Rejected) {
        return;
    } else {
        //
    }
    Param result = d.getData();
    Parameters* param = new Parameters(result);
    mDatabaseLeftCamera->addItem(param);
    mModelLeftCamera->select();
    ui->tableView->show();
}

Draw as many boxes as the user wants:

void MainWindow::onRubberBandUpdate(const QRect &viewportRect,
                                    const QPointF &fromScenePoint,
                                    const QPointF &toScenePoint)
{
    if(viewportRect.isNull() && fromScenePoint.isNull() && toScenePoint.isNull() && imageLoaded)
    {
        if(currentSelection >= 0)
                selections[currentSelection]->setActiveState(false);
            QRectF select;
            select.setCoords(start.x(), start.y(), end.x(), end.y());
            square = new Square(select);
            square->setActiveState(true);
            currentSelection = selections.size();
            selections.append(square);
            leftScene->addItem(square->getGraphics());
            ui->graphicsView->show();
    }
    else
    {
        start = fromScenePoint;
        end = toScenePoint;
    }
}

After drawing several boxes the user decides to reactivate one of the boxes by double-cliking within the box:

void MainWindow::onSceneDoubleClick(QPointF point)
{
    qDebug() << "Click!";
        QList<QGraphicsItem*> foundItems = leftScene->items(point);
        if(foundItems.size() > 0 && foundItems[0]->group() != nullptr)
        {
            qDebug() << "Found";
            int i = 0;
            for(i=0;i<selections.size();i++)
            {
                qDebug() << "Iterate";
                if(selections[i]->getGraphics() == foundItems[0]->group())
                {
                    qDebug() << "Target";
                    break;
                }
            }
            if(currentSelection >= 0)
                selections[currentSelection]->setActiveState(false);
            currentSelection = i;
            selections[currentSelection]->setActiveState(true);
        }
}

The user decides to erase the re-activated square:

void MainWindow::on_eraseSquare_clicked()
{
    clearSceneLeft();
}


void MainWindow::clearSceneLeft()
{
    if (selections.size() > 0) {
        qDeleteAll(selections);
        selections.clear();
        currentSelection = -1;
    }
    for(int p=0;p<shape.size();p++)
    {
        leftScene->removeItem(shape[p]);
        delete shape[p];
    }
        shape.clear();
}

But this is not working and nothing happens. Additionally because the box corresponds to an SQL reference on the QTableView I dont know how that could be connected in the SQL class.

I have been trying for many days to solve this problem and am running out of ideas. Thanks for shedding light on this problem or point in the right direction. If you would like to try the small example interface you can do it from here

来源:https://stackoverflow.com/questions/56572812/how-to-erase-a-qgraphicsitem-from-qgraphicsview-using-qpushbutton

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!