Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
}
like image 907
syc Avatar asked Oct 28 '25 17:10

syc


2 Answers

You should have your matrix variable as a private member in your model, so that all edits to the matrix should be done through functions in your model. that means your model will have a public transpose function that calls transpose on your matrix data then emit dataChanged() signal. And you shouldn't have any direct access to your matrix because changing it without the model's knowledge will not give what you want. that way, it isn't your responsibility to call updateAll after each change to the matrix variable since your model did the change and updated itself accordingly. . .

like image 66
Mike Avatar answered Oct 31 '25 09:10

Mike


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 :)

like image 20
syc Avatar answered Oct 31 '25 08:10

syc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!