如何彻底改变 QAbstractTableModel 的底层数据?
How to change underlying data of QAbstractTableModel completely?
这是我第一次post来这里,但自从我开始编程以来,我得到了你们所有人的很多帮助。
我是 Qt 的新手,目前正在尝试制作我的第一个项目。我的问题是关于模型、底层数据和视图之间的通信。
我首先将后台事物(数据存储等)与 GUI 分开。
现在我有一个模板 class Matrix
并且我写了一个模板 class MatrixModel
继承自 QAbstractTableModel
。这工作正常,意味着我可以编辑 table 并在视图和模型数据中刷新值。
现在我的问题是:如何在不编写新方法的情况下更改模型中的数据?
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);
有什么方法可以调用 m.transpose()
模型的基础数据吗?如果我更改 m
会怎样?它会影响模型的数据吗?我尝试了很多东西,但没有任何效果。一个 "problem" 是我不能使用标准 signal/slot 语法,因为我正在使用模板 classes.
我最后一次尝试是在模型中进行更新 class:
template<typename T>
void MatrixModel<T>::updateAll() {
QModelIndex topLeft = index(0,0);
QModelIndex bottomRight = index(rowCount()-1, columnCount()-1);
emit dataChanged(topLeft, bottomRight);
}
我试着用一个按钮和一个 lambda 函数连接它:
connect(transposeButton, &QPushButton::clicked, [=,&m,&model]() {
m.transpose(); model->updateAll();
});
但是如果我按下按钮,那似乎会使我的程序崩溃。我真的很绝望 xD 希望你能帮助我。如果您需要更多信息,请询问^^
此致
丹尼斯
编辑 1:好的,到目前为止我想通了(在你的帮助下 :)),我必须在模型中再次编写矩阵的函数(例如 transpose())并从那里发出数据变化(用发出 dataChanged 或 beginResetModel()...) 但我无法修改模型基础数据。如果我写
主窗口中的这个:
connect(transposeButton, &QPushButton::clicked, [&model]() {
model->transpose();
});
模型中的这个:
template<typename T>
void MatrixModel<T>::transpose() {
m(0,0) = 5;
}
如果我按下转置按钮,我的程序就会崩溃。如果我评论行
m(0,0) = 5;
出来了,一切正常。
编辑 2:
也许数据存储有问题,所以这是我的复制构造函数和我的矩阵的私有变量 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;
}
您应该将 matrix
变量作为模型中的私有成员,以便对 matrix
的所有编辑都应通过模型中的函数完成。这意味着您的模型将有一个 public transpose
函数,该函数在您的 matrix
数据上调用 transpose
然后发出 dataChanged()
信号。而且你不应该直接访问你的 matrix
因为在模型不知情的情况下改变它不会给你想要的东西。这样,在每次更改 matrix
变量后调用 updateAll
就不是您的责任,因为您的模型进行了更改并相应地更新了自身。 . .
我明白了...
connect(transposeButton, &QPushButton::clicked, [model]() {
beginResetModel();
m(0,0)=50;
endResetModel();
});
有效...模型已经是一个指针,所以我将相同的指针指向 lambda 函数。现在我只需要弄清楚我的转置函数有什么不对,因为它仍然无法正常工作,但崩溃已经消失了:P谢谢你的建议:)
这是我第一次post来这里,但自从我开始编程以来,我得到了你们所有人的很多帮助。
我是 Qt 的新手,目前正在尝试制作我的第一个项目。我的问题是关于模型、底层数据和视图之间的通信。
我首先将后台事物(数据存储等)与 GUI 分开。
现在我有一个模板 class Matrix
并且我写了一个模板 class MatrixModel
继承自 QAbstractTableModel
。这工作正常,意味着我可以编辑 table 并在视图和模型数据中刷新值。
现在我的问题是:如何在不编写新方法的情况下更改模型中的数据?
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);
有什么方法可以调用 m.transpose()
模型的基础数据吗?如果我更改 m
会怎样?它会影响模型的数据吗?我尝试了很多东西,但没有任何效果。一个 "problem" 是我不能使用标准 signal/slot 语法,因为我正在使用模板 classes.
我最后一次尝试是在模型中进行更新 class:
template<typename T>
void MatrixModel<T>::updateAll() {
QModelIndex topLeft = index(0,0);
QModelIndex bottomRight = index(rowCount()-1, columnCount()-1);
emit dataChanged(topLeft, bottomRight);
}
我试着用一个按钮和一个 lambda 函数连接它:
connect(transposeButton, &QPushButton::clicked, [=,&m,&model]() {
m.transpose(); model->updateAll();
});
但是如果我按下按钮,那似乎会使我的程序崩溃。我真的很绝望 xD 希望你能帮助我。如果您需要更多信息,请询问^^
此致
丹尼斯
编辑 1:好的,到目前为止我想通了(在你的帮助下 :)),我必须在模型中再次编写矩阵的函数(例如 transpose())并从那里发出数据变化(用发出 dataChanged 或 beginResetModel()...) 但我无法修改模型基础数据。如果我写
主窗口中的这个:
connect(transposeButton, &QPushButton::clicked, [&model]() {
model->transpose();
});
模型中的这个:
template<typename T>
void MatrixModel<T>::transpose() {
m(0,0) = 5;
}
如果我按下转置按钮,我的程序就会崩溃。如果我评论行
m(0,0) = 5;
出来了,一切正常。
编辑 2: 也许数据存储有问题,所以这是我的复制构造函数和我的矩阵的私有变量 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;
}
您应该将 matrix
变量作为模型中的私有成员,以便对 matrix
的所有编辑都应通过模型中的函数完成。这意味着您的模型将有一个 public transpose
函数,该函数在您的 matrix
数据上调用 transpose
然后发出 dataChanged()
信号。而且你不应该直接访问你的 matrix
因为在模型不知情的情况下改变它不会给你想要的东西。这样,在每次更改 matrix
变量后调用 updateAll
就不是您的责任,因为您的模型进行了更改并相应地更新了自身。 . .
我明白了...
connect(transposeButton, &QPushButton::clicked, [model]() {
beginResetModel();
m(0,0)=50;
endResetModel();
});
有效...模型已经是一个指针,所以我将相同的指针指向 lambda 函数。现在我只需要弄清楚我的转置函数有什么不对,因为它仍然无法正常工作,但崩溃已经消失了:P谢谢你的建议:)