Search code examples
c++qttemplatesqtableviewqabstracttablemodel

How to change underlying data of QAbstractTableModel completely?


This is my first post here, but i received a lot of help from all of you guys, since i started programming.

I am new to Qt and try to make my first project at the moment. My question is about the communication between the model, the underlying data and the view.

I first made the background things (data storing etc.) separate from the GUI. Now I have a template class Matrix and I wrote a template class MatrixModel which inherits from QAbstractTableModel. This is working fine, means that I can edit the table and the values refresh in the view and in the data from model.

Now my question: How do I change the data in the model without writing a new method?

mainwindow.cpp:

matrix<int> m = {{1,2,3},{4,5,6},{7,8,9}};
MatrixModel<int>* model = new MatrixModel<int>(m);
QTableView* tableView = new QTableView;
tableView->setModel(model);

Is there any way to call m.transpose() to the model's underlying data? What happens if I change m? Does it affect the model's data? I tried a lot of things but nothing worked. One "problem" is that I can't use standard signal/slot syntax because I'm working with template classes.

My last try was to make an update class in the model:

template<typename T>
void MatrixModel<T>::updateAll() {
    QModelIndex topLeft = index(0,0);
    QModelIndex bottomRight = index(rowCount()-1, columnCount()-1);
    emit dataChanged(topLeft, bottomRight);
}

and I tried to connect it with a button and a lambda function:

connect(transposeButton, &QPushButton::clicked, [=,&m,&model]() {
m.transpose(); model->updateAll();
});

but that seemed to crash my program if i press the button. I am really desperated xD hope you can help me. If you need more information please just ask^^

Best Regards

Dennis

EDIT 1: Okay so far i figured out (with your help :)), that I have to write the functions of the matrix again in the model (e.g. transpose()) and emit data changes from there (with emit dataChanged or beginResetModel()...) but I can't modify the models underlying data. If I write

This in the mainwindow:

connect(transposeButton, &QPushButton::clicked, [&model]() {
    model->transpose();
});

This in the Model:

template<typename T>
void MatrixModel<T>::transpose() {
    m(0,0) = 5;
}

my program just crashes if i press the button transpose. If i comment the line

m(0,0) = 5;

out, everything works.

EDIT 2: Maybe there is a problem with the data storage, so here is my copy constructor and the private variables of my matrix class:

private:
std::vector <T> data;
size_t rows, columns;

//Copy constructor
template<typename T>
matrix<T>::matrix(const matrix<T>& other)
    : rows(other.rows), columns(other.columns) {
    data = other.data;
}

Solution

  • I got it...

    connect(transposeButton, &QPushButton::clicked, [model]() {
        beginResetModel();
        m(0,0)=50;
        endResetModel();
    });
    

    works... model already is an pointer, so i give the same pointer to the lambda function. Now i just have to figure out what is not right with my transpose function because this is still not working, but the crashes are gone :P thank you for your suggestions :)