how to insert or delete a QAbstractTableModel row from a menubar
-
I have many QAbstractTableModel setup that are able to (data) (setdata) (rowcount)(column count)(headerData)(insertRows)(removeRows)
my mainwindow looks like this.
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); createMenus(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::createMenus() { fileMenu = menuBar()->addMenu(tr("&File")); openAction = new QAction(tr("&Open"), this); fileMenu->addAction(openAction); QObject::connect(openAction, &QAction::triggered, this, &MainWindow::openFile); fileMenu->addSeparator(); saveAction = new QAction(tr("&Save"), this); fileMenu->addAction(saveAction); QObject::connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile); fileMenu->addSeparator(); exitAction = new QAction(tr("&Exit"), this); fileMenu->addAction(exitAction); QObject::connect(exitAction, &QAction::triggered, this, &MainWindow::close); QMenu *toolMenu = menuBar()->addMenu(tr("&Tools")); QAction *insertAction = new QAction(tr("&Insert Row"), this); toolMenu->addAction(insertAction); QObject::connect(insertAction, &QAction::triggered, this, &MainWindow::insertRow); toolMenu->addSeparator(); QAction *removeAction = new QAction(tr("&Remove Row"), this); toolMenu->addAction(removeAction); QObject::connect(removeAction, &QAction::triggered, this, &MainWindow::removeRow); } void MainWindow::openFile() { //Open Data file } void MainWindow::saveFile() { //Save Data file } void MainWindow::insertRow() { //insert new row from QAbstractTableModel } void MainWindow::removeRow() { //remove new row from QAbstractTableModel }
Here is my insert and remove functions from the QAbstractTableModel
bool Data::insertRows(int position, int rows, const QModelIndex &index) { Q_UNUSED(index); beginInsertRows(QModelIndex(), position, position + rows - 1); for (int row = 0; row < rows; ++row) { m_data.insert(position, { QString().toUShort(), QString().toUShort(), QString().toUShort() }); } endInsertRows(); return true; } bool Data::removeRows(int position, int rows, const QModelIndex &index) { Q_UNUSED(index); beginRemoveRows(QModelIndex(), position, position + rows - 1); for (int row = 0; row < rows; ++row) { m_data.removeAt(position); } endRemoveRows(); return true; }
-
I have many QAbstractTableModel setup that are able to (data) (setdata) (rowcount)(column count)(headerData)(insertRows)(removeRows)
my mainwindow looks like this.
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); createMenus(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::createMenus() { fileMenu = menuBar()->addMenu(tr("&File")); openAction = new QAction(tr("&Open"), this); fileMenu->addAction(openAction); QObject::connect(openAction, &QAction::triggered, this, &MainWindow::openFile); fileMenu->addSeparator(); saveAction = new QAction(tr("&Save"), this); fileMenu->addAction(saveAction); QObject::connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile); fileMenu->addSeparator(); exitAction = new QAction(tr("&Exit"), this); fileMenu->addAction(exitAction); QObject::connect(exitAction, &QAction::triggered, this, &MainWindow::close); QMenu *toolMenu = menuBar()->addMenu(tr("&Tools")); QAction *insertAction = new QAction(tr("&Insert Row"), this); toolMenu->addAction(insertAction); QObject::connect(insertAction, &QAction::triggered, this, &MainWindow::insertRow); toolMenu->addSeparator(); QAction *removeAction = new QAction(tr("&Remove Row"), this); toolMenu->addAction(removeAction); QObject::connect(removeAction, &QAction::triggered, this, &MainWindow::removeRow); } void MainWindow::openFile() { //Open Data file } void MainWindow::saveFile() { //Save Data file } void MainWindow::insertRow() { //insert new row from QAbstractTableModel } void MainWindow::removeRow() { //remove new row from QAbstractTableModel }
Here is my insert and remove functions from the QAbstractTableModel
bool Data::insertRows(int position, int rows, const QModelIndex &index) { Q_UNUSED(index); beginInsertRows(QModelIndex(), position, position + rows - 1); for (int row = 0; row < rows; ++row) { m_data.insert(position, { QString().toUShort(), QString().toUShort(), QString().toUShort() }); } endInsertRows(); return true; } bool Data::removeRows(int position, int rows, const QModelIndex &index) { Q_UNUSED(index); beginRemoveRows(QModelIndex(), position, position + rows - 1); for (int row = 0; row < rows; ++row) { m_data.removeAt(position); } endRemoveRows(); return true; }
-
Is there a way to grab the QModelIndex pointer and insert and remove them from there?
Am i forced to call the data object to be able to insert or remove.
What do i do if i have many qabstractablemodels?
@Styx
Hi
1:
grab from where?
Normally it would be via a selection to say which row to removeQModelIndexList indexList = yourTableView->selectionModel()->selectedIndexes(); foreach (QModelIndex index, indexList) { .... }
2: Am i forced to call the data object to be able to insert or remove.
Well the model holds the data so seems ok to use that to delete some data.3:
Well then just make the removeRow wrapper function take a QAbstractTableModel * as paramter as
to reuse the same code. -
@Styx
Hi
1:
grab from where?
Normally it would be via a selection to say which row to removeQModelIndexList indexList = yourTableView->selectionModel()->selectedIndexes(); foreach (QModelIndex index, indexList) { .... }
2: Am i forced to call the data object to be able to insert or remove.
Well the model holds the data so seems ok to use that to delete some data.3:
Well then just make the removeRow wrapper function take a QAbstractTableModel * as paramter as
to reuse the same code.@mrjj Q
ModelIndexList indexList = yourTableView->selectionModel()->selectedIndexes();
foreach (QModelIndex index, indexList) {
....
}the code above may have issues. After the first is removed, the second index will change, except the index list is sorted with reverse row order.
I just did it in my code for qtreeview. Hope it helps.
while( selectedIndexes().size() > 0 ) { auto idx = selectedIndexes().at( 0 ); /* deselect idx first */ selectionModel()->setCurrentIndex( idx, QItemSelectionModel::Deselect ); if ( true == m_fileSystemModel->isDir( idx ) ) { m_fileSystemModel->rmdir( idx ); } else { m_fileSystemModel->remove( idx ); } }
-
How I end up doing it was..
create two public slots to insert and remove
void Data::insertDataRow() { // Always removes a row at the end of the tableView insertRows(RowCounter,1); } void Data::insertDataRow() { // Always inserts a row at the end of the tableView removeRows(RowCounter,1); }
Then inside my function that reads the info
void MainWindow::openFile() { // Grab the file do a bunch of shit here QTableView *tableView = new QTableView; setCentralWidget(tableView); m_data = new Data("read some data", this); tableView->setModel(m_data); tableView->setSortingEnabled(false); tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); tableView->horizontalHeader()->show(); tableView->show(); //Connect the insert and remove action to the Data public slots QObject::connect(insertAction, &QAction::triggered, m_data, &Data::insertDataRow); QObject::connect(removeAction, &QAction::triggered, m_data, &Data::removeDataRow); }
I've got a huge Case system that controls all my qabstractablemodels all I have to do is connect the signal and slots to the respective objects.
Only bugs are that if you remove the last row it crashes the program but a simple check on the row and position should fix that.