У меня есть небольшой .ui
, состоящий из (я помещаю только основные компоненты, связанные с проблемой):
1) N.1 QGraphicsView
2) N.1 QTableView
3) N.1 QPushButton
После загрузки изображений на QGraphicsView
пользователь может захватывать часть изображений, рисуя прямоугольники с помощью мыши вокруг интересующей функции. Операция с боксом выполняется в class Square
.
Каждый раз, когда пользователь хочет сохранить извлеченное поле, при щелчке правой кнопкой мыши открывается небольшое диалоговое окно, в котором запрашивается имя для извлеченного изображения. После нажатия кнопки «Принять» в диалоговом окне эта функция (или поле) сохраняется в виде строки QTableView
. Теперь, если пользователь хочет стереть блок, просто дважды щелкните на нем и, используя QPushButton
, он должен стереть выделенное поле и индекс QTableView
, но этого не происходит. Очень недавно Мне удалось успешно реализовать оператор SQL
, который заботится об удалении индекса строк (только SQL
), а не саму реализацию QModelIndex
из-за моих недостаточных знаний о этот инструмент предлагает Qt5
. Хотя я много читал о официальной документации и нашел полезные источники
Некоторые способы, которыми я до сих пор пытался сделать эту работу:
1) Я создал каркас из SQL
, используя QSQLITE
, который обрабатывает все операции SQL
, недавно я добавил дополнительную операцию, которая стирает параметры, как это можно увидеть ниже. Я стираю только индекс, связанный с QTableView
, так как это также должно стереть все оставшиеся поля. См. SQL
заявления ниже:
dataleftcamera.h
class dataLeftCamera : public QObject
{
Q_OBJECT
public:
explicit dataLeftCamera(QObject *parent = nullptr);
QString getError() const { return mError; }
bool addItem(Parameters* mParameters);
bool updateItem(int itemId, Parameters* mParameters);
bool removeItem(int itemId);
QSqlDatabase getDatabase();
private:
QString mError;
QSqlDatabase mDatabaseLeft;
};
dataleftcamera.cpp
bool dataLeftCamera::removeItem(int itemId)
{
QSqlQuery qry;
qry.prepare("DELETE FROM leftCamTable WHERE id = ?");
qry.addBindValue(itemId);
bool ok = qry.exec();
if(!ok) {
mError = qry.lastError().text();
qDebug() << mError;
}
}
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
// Set up Constructor
connect(ui->eraseSquare, SIGNAL(clicked()), this, SLOT(on_eraseSquare_clicked(QModelIndex)));
}
Пользователи могут нарисовать столько коробок, сколько захотят. Обратите внимание, что вот где class Square
, описанный выше square = new Square(select);
, вступает в игру:
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::on_eraseSquare_clicked(const QModelIndex &index)
{
int row = index.row();
Param currentData;
int ItemId = index.sibling(row, 0).data().toInt();
mDatabaseLeftCamera->removeItem(ItemId);
mModelLeftCamera->select();
ui->tableView->show();
}
Дважды щелкните, чтобы заново активировать окно:
void MainWindow::onSceneDoubleClick(QPointF point)
{
QList<QGraphicsItem*> foundItems = leftScene->items(point);
if(foundItems.size() > 0 && foundItems[0]->group() != nullptr)
{
int i = 0;
for(i=0;i<selections.size();i++)
{
if(selections[i]->getGraphics() == foundItems[0]->group())
{
break;
}
}
if(currentSelection >= 0)
selections[currentSelection]->setActiveState(false);
currentSelection = i;
selections[currentSelection]->setActiveState(true);
}
}
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;
}
Square::~Square() {}
QRectF Square::boundingRect() const { return QRectF(0,0,50,50); }
QGraphicsItemGroup *Square::getGraphics() { return gfx; }
bool Square::removeRows(int position, int rows, const QModelIndex &index)
{
beginRemoveRows(QModelIndex(), position, position+rows-1);
for (int row = 0; row < rows; ++row) {
stringList.removeAt(position);
}
endRemoveRows();
return true;
}
void Square::setModelIndex(const QModelIndex &)
{
// Needed?
}
void Square::beginRemoveRows(const QModelIndex &parent, int first, int last)
{
// Needed?
}
void Square::endRemoveRows()
{
// Needed?
}
square.h
class Square : public QObject
{
Q_OBJECT
public:
explicit Square(QRectF newarea);
~Square();
QGraphicsRectItem *mItemSquare;
bool pressed;
bool drawStarted;
int selectedTool, index;
QPixmap mPix;
QGraphicsItemGroup* getGraphics();
bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex());
void setModelIndex(const QModelIndex&);
void setPen(QPen newpen);
void updateColor(QColor active, QColor inactive);
public slots:
void setActiveState(bool newactive);
void setVisible(bool newstate);
protected:
void beginRemoveRows(const QModelIndex &parent, int first, int last);
void endRemoveRows();
}
2) Я читал много источников, таких как , этот и этот источник . Похоже, что QTableView
должен быть подкласс для повторной реализации
beginRemoveRows
и endRemoveRows
. Но в то же время я не уверен, что это нужно делать.
3) Третий способ, которым я пытался понять, возможно ли это создать функцию на class Square
, подобную этой:
void Square::setModelIndex(const QModelIndex &)
{
// possible solution?
}
Должна ли реализация в этот момент выглядеть примерно так?
Я застрял в этой проблеме уже несколько дней, и у меня нет дополнительных идей, чтобы двигаться дальше.
Большое спасибо за указание в правильном направлении для реализации функции QModelIndex
и решения этой проблемы.