Как удалить QGraphicsItem из QGraphicsView, используя QPushButton - PullRequest
0 голосов
/ 13 июня 2019

Я строю основной пользовательский интерфейс, но я застрял в проблеме, и чтобы уменьшить проблему, я создаю небольшой рабочий пример, который несет именно проблему.

После того, как пользователь создает новый файл .db, используя значок и сохраняя, например, на рабочем столе, можно загружать изображения (пока только в формате .png) в QGraphicsView и щелкать по checkbox для включения от Right: Drag до Right:Select можно нарисовать прямоугольники на изображении. С right click внутри нарисованного прямоугольника мы можем открыть QDialog, который просит назвать извлеченное изображение из прямоугольника. Изображение сохраняется в QTableView, как показано в небольшом рабочем примере ниже:

sql

Проблема : Я пробовал несколько способов стереть блок (и связанный индекс на QTableView соответствующего блока), но ни один из них не был успешным. С использованием "Erase Square" QPushButton пытаюсь стереть коробку. Каждую коробку можно активировать, просто оставив double-clicking в соответствующей ячейке. Смотрите ниже, чего я пытаюсь достичь:

problem

Я рисую коробку на QGraphicsView и щелкаю правой кнопкой мыши, чтобы захватить изображение из коробки:

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

Нарисуйте столько квадратов, сколько хочет пользователь:

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

После рисования нескольких блоков пользователь решает повторно активировать один из блоков, дважды щелкнув по нему:

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

Пользователь решает стереть повторно активированный квадрат:

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

Но это не работает, и ничего не происходит. Кроме того, поскольку поле соответствует ссылке SQL на QTableView, я не знаю, как это можно подключить в классе SQL.

Я много дней пытался решить эту проблему, и у меня заканчиваются идеи. Спасибо за то, что пролили свет на эту проблему или указали правильное направление. Если вы хотите попробовать небольшой пример интерфейса, вы можете сделать это с здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...