我如何保持我的QAbstractTableModel与我的数据存储同步
How do I keep my QAbstractTableModel in sync with my data store?
在我的应用程序中,我有一个类来保存项目列表:
class Database : public QObject
{
Q_OBJECT
public:
Database(QObject *parent, const QString &name);
const Entry& item(int idx) const { Q_ASSERT(idx < itemCount()); return _items.at(idx); }
const QString& name() const { return _name; }
int itemCount() const { return _items.size(); }
bool addItem(const Entry &item);
bool addItems(const Database *source, const QList<int> &idxs);
bool updateItem(int idx, const Entry &updated);
void removeItem(int idx);
void removeItems(const QList<int> &idxs);
private:
QList<Entry> _items;
signals:
void itemsRemoved(int start, int count);
void itemsAdded(int count);
void itemChanged(int index);
void countUpdate();
};
项操作函数(add、update、remove)在完成操作(添加、更改、删除项)时发出相应的信号。我有这样的数据库的列表和一个QTableView显示他们的内容。我还有一个定制的对象,qabstracttablemodel派生的模型类,它可以在需要时指向(并显示)不同的数据库:
class DatabaseModel : public QAbstractTableModel
{
Q_OBJECT
public:
DatabaseModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const { return _data->itemCount(); }
int columnCount(const QModelIndex &parent = QModelIndex()) const { return 5; };
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const = 0;
void setDatabase(const Database *data);
{
beginResetModel();
_data = data;
endResetModel();
}
protected:
const Database *_data;
};
我有一个问题,使模型反映其当前数据库的变化。在此之前,我通过每次数据库中的某些更改(由从数据库到DatabaseModel的信号触发)发出模型重置来实现它的工作,但我认为这有点过头了。现在我不知道如何正确连接数据库和模型。
将Database信号连接到模型并使模型发出datachchanged()不起作用,因为Database中的项数(因此模型的行数)正在变化。在QAbstractTableModel中有称为rowsInserted()和rowsRemoved()的信号,但是文档说它们不能在自定义类中使用。有一些虚函数要重新实现,叫做removeRows()和insertRows(),但是文档说我必须在它们里面调用begin(Remove|Insert)Rows()和end(Remove|Insert)Rows(),这会导致两个问题:
- Rows()需要一个QModelIndex '父'参数,我不知道该使用什么
- 文档说这些函数需要在更改底层数据存储 之前调用
EDIT:实际上这并不重要,现在我正在传递QModelIndex()。QAbstractTreeModel使用它来标识树中的父节点,对于表模型显然不是必需的。
如何使模型与数据库保持同步?谢谢!
我想我明白你的问题了。一方面,你正在做正确的事情,并试图保持数据与模型分离,另一方面,你的数据不知道模型本身。
在更改数据之前调用begin…Rows(),然后调用end…Rows()是有原因的。即QPersistentModelIndex
。通常情况下,您不应该对QModelIndex
对象进行保存,但是持久化索引应该被保存和保留。模型必须保证其有效性。看看begin…Rows()方法的代码,它主要是关于那些持久索引的。
你有几个选择。
a)如果你确信你不会使用持久索引,你可以在你的模型中实现一个私有槽,它可以从你的数据源中侦听一种更新信号。这个槽只调用begin…Rows()和end…Rows(),中间没有任何内容。它不"干净",但它会工作。
b)您可以在数据源中实现更多信号,一个信号表示数据更改的开始(例如删除或添加一行),另一个信号表示所述操作的结束。当然,这会大大增加代码的大小。
c)你可以把你的DataBase
类在模型中作为朋友,并调用begin…结束……方法,但是DataBase
必须知道模型。
DataBase
类作为模型的数据存储和代码其他部分的接口,对吗?使用自定义项和操作模型本身的方法不是更容易吗,从而避免了麻烦?我已经做了我的公平分享,所以我可以给你的代码,如果需要的话。
希望这对你有帮助。
最好的祝福
- 我的头文件 DNode 中的我的数据类型未被识别为数据类型
- 遍历我的数据结构,并向其中输入随机值
- 为什么操作系统正在更改我的数据包的指定传出端口
- 我的数据结构的最佳序列化方法
- 为什么我的数据/输出文件为空?
- 为什么调整大小的 2D 矢量会重置我的数据
- 为什么我的数据不适合CUDA纹理对象
- C 使用与自定义类对象的列表容器,列表:: Sort函数实际上并未对我的数据进行排序
- 为什么我的数据无法在信号/插槽的表格之间传输
- 为什么返回数据结构而不是指针弄乱了我的数据的完整性
- 使用boost :: iterator_range;我的数据在哪里范围
- 为什么我的数据流在20或30行后开始重复
- C++:如何使用冒泡排序来重新排列我的数据
- 如何将自动递增的主键的数据从 sql 服务器获取到我的数据网格视图
- 如何将 0(且仅 0)转换为我的数据结构
- C++模来对齐我的数据
- 谁应该有一个迭代器,我的数据类或该类中的实际列表
- 如何只训练我的数据一次
- COM互操作传递了错误的指针,我的数据只有一个字节
- 当从c++传递缓冲区到NodeJS时,我的数据消失了