QTreeView and QTableView dynamic changes


Dynamically adding items to QTreeView and QTableView

Create the UI as follows, with the treeview on the left hand side and the table view on the right hand side.

Notes

The header file contains the models and the selection models for the tree view and the table view:
    QStandardItemModel *treeViewModel;
    QItemSelectionModel *treeViewSelectionModel;
    QItemSelectionModel *tableSelectionModel;
    QStandardItemModel *tableModel;
In the .cpp file, the tree view models and table view models are set as the models for the selection models.
treeViewSelectionModel->setModel(treeViewModel);
tableSelectionModel->setModel(tableModel);
The following code illustrates how to dynamically add a new row to the treeview.
void MainWindow::updateTreeView()
{
    QStandardItem *newRow = new QStandardItem(QString("inserted row"));
    QList<QStandardItem *>newRows;
    newRows.append(newRow);
    auto first = treeViewSelectionModel->selection().indexes().first();
    QStandardItem *existingItem = treeViewModel->itemFromIndex(treeViewModel->index(first.row(),first.column(),first.parent()));
    existingItem->appendRows(newRows);
}
The following code would be needed to dynamically remove a row from the treeview (at the end of the updateTreeView function):
   model->removeRows(first.row(),1,first.parent());
The following code illustrates how to dynamically add a new row to the table view:
void MainWindow::updateTableView()
{
    QStandardItem *newCell1 = new QStandardItem(QString("new cell1"));
    QStandardItem *newCell2 = new QStandardItem(QString("new cell2"));
    auto rowIndexToRemove = tableSelectionModel->selection().indexes().first();
    tableModel->insertRow(tableModel->rowCount(QModelIndex())); // insert an empty row
    tableModel->setItem(tableModel->rowCount()-1,0,newCell1);
    tableModel->setItem(tableModel->rowCount()-1,1,newCell2);

}
The following code is needed instead of the insertRow, and the two setItems in the updateTableView function to remove a row dynamically from the table view:
    tableModel->removeRow(rowIndexToRemove.row(),QModelIndex()); //e.g. of removing a row
The complete source code follows:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStandardItemModel>
#include <QItemSelectionModel>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void initializeTableViewAndModel();
    void initializeTreeViewAndModel();

    void updateTableView();
    void updateTreeView();

private:
    void init();
    Ui::MainWindow *ui;
    QStandardItemModel *treeViewModel;
    QItemSelectionModel *treeViewSelectionModel;
    QItemSelectionModel *tableSelectionModel;
    QStandardItemModel *tableModel;


private slots:
    void on_pushButton_clicked();
};
#endif // MAINWINDOW_H 
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QList>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init();
}

MainWindow::~MainWindow()
{
    delete ui;
}



void MainWindow::init()
{
    initializeTreeViewAndModel();
    initializeTableViewAndModel();
}

void MainWindow::initializeTreeViewAndModel()
{
    treeViewModel = new QStandardItemModel();
    QStringList headers;
    headers << "My Items";
    treeViewModel->setHorizontalHeaderLabels(headers); //set the header labels.

    QStandardItem *root = treeViewModel->invisibleRootItem(); //invisible root item is the root of all the items.
    for(int p = 0; p < 5; p++)
    {
        QStandardItem * parentItem = new QStandardItem(QString("Parent %0").arg(p)); //first level of the tree
        root->appendRow(parentItem);
        for(int c = 0; c < 5; c++)
        {
            QStandardItem *childItem = new QStandardItem(QString("Child %0").arg(c));  //second level of the tree
            parentItem->appendRow(childItem);
        }
    }
    ui->treeView->setModel(treeViewModel);
    treeViewSelectionModel = new QItemSelectionModel();
    treeViewSelectionModel->setModel(treeViewModel);  //VERY IMPORTANT.
    ui->treeView->setSelectionModel(treeViewSelectionModel);
}


void MainWindow::initializeTableViewAndModel()
{
    tableModel = new QStandardItemModel();
    tableModel->insertRows(0,4);
    tableModel->insertColumns(0,2);
    QStringList headers;
    headers << "Task" << "Priority";
    tableModel->setHorizontalHeaderLabels(headers);
    int counter = 1;

        for(int r = 0; r < tableModel->rowCount(); r++)
        {
            for(int c = 0; c < tableModel->columnCount(); c++)
            {
                //QStandardItem* item = new QStandardItem(QString("row %0 col %1").arg(r).arg(c));
                QStandardItem* item = new QStandardItem(QString("%0").arg(counter));
                tableModel->setItem(r,c,item);
                counter++;
            }
        }
    ui->tableView->setModel(tableModel);
    tableSelectionModel = new QItemSelectionModel();
    tableSelectionModel->setModel(tableModel);
    ui->tableView->setSelectionModel(tableSelectionModel);
    ui->tableView->setSortingEnabled(true);
}



void MainWindow::updateTreeView()
{
    QStandardItem *newRow = new QStandardItem(QString("inserted row"));
    QList<QStandardItem *>newRows;
    newRows.append(newRow);
    auto first = treeViewSelectionModel->selection().indexes().first();
    QStandardItem *existingItem = treeViewModel->itemFromIndex(treeViewModel->index(first.row(),first.column(),first.parent()));
    existingItem->appendRows(newRows);
   //model->removeRows(first.row(),1,first.parent());
}

void MainWindow::updateTableView()
{
    QStandardItem *newCell1 = new QStandardItem(QString("new cell1"));
    QStandardItem *newCell2 = new QStandardItem(QString("new cell2"));
    auto rowIndexToRemove = tableSelectionModel->selection().indexes().first();
    tableModel->insertRow(tableModel->rowCount(QModelIndex())); // insert an empty row
    tableModel->setItem(tableModel->rowCount()-1,0,newCell1);
    tableModel->setItem(tableModel->rowCount()-1,1,newCell2);
    //tableModel->removeRow(rowIndexToRemove.row(),QModelIndex()); e.g. of removing a row

}

void MainWindow::on_pushButton_clicked()
{
   updateTreeView();
   updateTableView();
} 

Comments

Popular posts from this blog

C++ strings and string_view