Как удалить ссылочный индекс QSQLITE, связанный с QGraphicsItem, из QTableView - PullRequest
0 голосов
/ 04 марта 2019

У меня небольшой пользовательский интерфейс, куда я загружаю изображения, используя QPushButton.Я могу нарисовать квадраты на загруженном изображении, включив QCheckBox.Как только я рисую квадрат, я создаю ссылочный индекс в QTableView.Так, например, на приведенном ниже экране печати у меня есть четыре (N.4) красных квадрата, которые эквивалентны четырем (N.4) индексам QTableView.См. GUI ниже:

gui

Можно повторно активировать старый квадрат, дважды щелкнув внутри него.В случае, если пользователю больше не нужен активный квадрат, использование QPushButton «Стереть квадрат» сотрет активный квадрат, а также соответствующую строку (ссылочный индекс) QTableView.

Однако, каккак только я пытаюсь стереть квадрат, вылетает графический интерфейс.Я не уверен, как справиться с этим исключением.Функция, которая стирает поле ниже и называется clearSceneLeft().Однако я не уверен, является ли это также проблемой, связанной с QSQLITE, поскольку каждый блок в основном эквивалентен строке внутри QTableView.

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

mouseDoubleClicked(QPointF), присутствующий в конструкторе MainWindow в rubberband, обрабатывается классом graphicsForClick, и я сообщаю ниже только о наиболее важных частях:

graphisforclick.h

class graphicsForClick : public QGraphicsScene
{
    Q_OBJECT
public:
    explicit graphicsForClick(QObject *parent = nullptr);
    virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent * mouseEvent);
    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent);
    signals:
    void mouseReleased(QPointF point);
    void rightClick(QPointF point);
    void mouseDoubleClicked(QPointF point);
};

graphisforclick.cpp

graphicsForClick::graphicsForClick(QObject *parent):
    QGraphicsScene(parent)
{}

void graphicsForClick::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    mouseDoubleClicked(mouseEvent->scenePos());
    QGraphicsScene::mouseDoubleClickEvent(mouseEvent);
}

void graphicsForClick::mouseReleaseEvent(QGraphicsSceneMouseEvent * me)
{
    if(me->button() == Qt::LeftButton)
        mouseReleased(me->scenePos());
    else rightClick(me->scenePos());
    QGraphicsScene::mouseReleaseEvent(me);
}

В главном окне я установил все элементы управления rubberband, которые обрабатываютdoubleClick и QPushButton on_eraseSquare_clicked() обрабатывается:

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    leftScene = new graphicsForClick();
    ui->graphicsView->setScene(leftScene);
    ui->graphicsView->show();
    currentSelection = -1;
    mDatabaseLeftCamera = new dataLeftCamera(this);
    mModelLeftCamera = nullptr;
    mModelLeftCamera = new QSqlTableModel(this);
    ui->tableView->setModel(mModelLeftCamera);
    connect(leftScene, SIGNAL(mouseDoubleClicked(QPointF)),
            this, SLOT(onSceneDoubleClick(QPointF)));
}

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

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

mainwindow.h

private:
    QList<QGraphicsRectItem*> shape;

setActiveState обрабатывается классом Square.Таким образом, каждый раз, когда пользователь рисует квадрат, то есть активный квадрат, а когда пользователь рисует второй квадрат, это активный квадрат, а предыдущий квадрат также деактивирует изменение цвета.Ниже приведены наиболее важные части кода, связанные с этим классом:

square.cpp

Square::Square(QRectF newarea)
{
    colorActive = Qt::red;
    colorInactive = Qt::darkRed;
    mItemSquare = new QGraphicsRectItem(newarea);
    mItemSquare->setPen(QPen(colorActive));
    gfx = new QGraphicsItemGroup();
    gfx->addToGroup(mItemSquare);
    index = -1;
}

void Square::updateColor(QColor active, QColor inactive)
{
    colorActive = active;
    colorInactive = inactive;
}

void Square::setActiveState(bool newactive)
{
    active = newactive;
    if(active)
    {
        mItemSquare->setPen(QPen(colorActive));
    }
    else
    {
        mItemSquare->setPen(QPen(colorInactive));
    }
}

void Square::setVisible(bool newstate)
{
    mItemSquare->setVisible(newstate);
}

Ошибка компилятора:

ASSERT failure in QList<T>::operator[]: "index out of range"

Если проще взглянуть, исходный код минимального проверяемого примера: git clone https://ERaggi@bitbucket.org/ERaggi/reference.git

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

...