创建 QAbstractModelItem 的代理
我正在编写一个 Qt 应用程序来实现非常大的数据集的可视化。
所以,我有一个 SourceDataModel
类,继承自 QAbstractItemModel
,它似乎工作正常(目前,我只在 QTableView/QTreeView 中显示它,但稍后,我将创建一些自定义视图)。
现在,我希望能够过滤这些数据,即
能够拥有不同的数据 分辨率(即仅暴露 1 2)
中的数据项能够 对数据应用一些过滤器(即 将 Unix 时间戳显示为 dd/MM/yyyy hh:mm:ss)
所以我开始创建一个 ProxySourceDataModel 类,它继承自我的 SourceDataModel 并存储一个实例,基本上将所有内容委托给实例。从这个 ProxySourceDataModel 中,我注意到当我在 QTableView 中使用它时没有显示任何数据。经过一番调查,似乎是因为我必须从底层 SourceDataModel 转发信号和槽。没问题,我做到了。
但仍然存在两个问题,我不知道如何处理它们:
我无法选择视图中的数据。如果我直接使用
SourceDataModel
,没有问题。但是使用 ProxySourceDataModel 我无法选择任何内容。数据根本没有被过滤!我在 ProxySourceDataModel 中重载了 data(),并将所有其他调用转发给底层的 SourceDataModel。但仍然只调用了
SourceDataModel::data()
。
这是一些代码来说明我正在做的事情:
class SourceDataModel : public QAbstractItemModel
{
//...
};
class ProxySourceDataModel : public SourceDataModel
{
public:
ProxySourceDataModel(SourceDataModel& model)
: model_(model)
{
// For all QAbstractItemModel's signals emitted by the underlying model,
// I propagate them like this
QObject::connect( &model_, SIGNAL( the_signal()),
this, SLOT (forward_the_signal())) ;
}
slots:
void forward_the_signal()
{
emit the_signal();
}
public:
// For all QAbstractItemModel's virtual function, I do something like this
virtual void the_function()
{
model_.the_function();
}
// This is where I was hoping to do the filtering
virtual QVariant data( const QModelIndex& index,int role=Qt::DisplayRole )
{
return filter( model_.data(index,role) );
}
private:
SourceDataModel& model_;
};
SourceDataModel sourceDataModel;
QTableView view;
view.setModel( new ProxySourceDataModel(sourceDataModel) );
非常感谢任何帮助或建议,感谢您的阅读!
-------------------- 编辑 ------------------------
我找到了!
问题是视图不使用其模型中的 QAbstractItemModel::data()
,而是调用 QModelIndex::data( )
其项目,进而调用项目底层模型的 QAbstractItemModel::data()
。 由于我的代理从底层模型返回模型索引,这就是为什么总是调用 SourceDataModel::data()
而不是 ProxySourceDataModel()
!
我刚刚重新实现了 ProxySourceDataModel::index() 来返回本地索引,它的工作方式就像一个魅力。 访问在 QT 中,链接模型无法按预期工作 了解更多信息。
谢谢!
I'm writing a Qt application to allow the visualization of very heavy data sets.
So, I have a SourceDataModel
class, inheriting from QAbstractItemModel
that seems to work properly (currently, I only display it in QTableView/QTreeView but later on, I'll create some custom views).
Now, I would like to be able to filter this data, that is
being able to have different data
resolution (i.e. only exposing 1
data item out of 2)being able to
apply some filters on the data (i.e.
displaying unix timestamps as
dd/MM/yyyy hh:mm:ss)
So I started to create a ProxySourceDataModel
class, which inherits from my SourceDataModel
and stores one instance, and basically delegates everything to the instance. From this ProxySourceDataModel
, I noticed that no data was displayed when I used it in a QTableView
. After some investigation, it seems that it was because i had to forward the signals and slots from the underlying SourceDataModel
. No problem, i did it.
But still 2 problems remain, and I can't figure out how to handle them:
I am not able to select the data in the views. If I use the
SourceDataModel
directly, no problem. But using theProxySourceDataModel
i can't select anything.The data is not filtered at all! I overloaded data() in
ProxySourceDataModel
, and forward all the other calls to the underlyingSourceDataModel
. But still, onlySourceDataModel::data()
is called.
Here is some code to illustrate what I'm doing:
class SourceDataModel : public QAbstractItemModel
{
//...
};
class ProxySourceDataModel : public SourceDataModel
{
public:
ProxySourceDataModel(SourceDataModel& model)
: model_(model)
{
// For all QAbstractItemModel's signals emitted by the underlying model,
// I propagate them like this
QObject::connect( &model_, SIGNAL( the_signal()),
this, SLOT (forward_the_signal())) ;
}
slots:
void forward_the_signal()
{
emit the_signal();
}
public:
// For all QAbstractItemModel's virtual function, I do something like this
virtual void the_function()
{
model_.the_function();
}
// This is where I was hoping to do the filtering
virtual QVariant data( const QModelIndex& index,int role=Qt::DisplayRole )
{
return filter( model_.data(index,role) );
}
private:
SourceDataModel& model_;
};
SourceDataModel sourceDataModel;
QTableView view;
view.setModel( new ProxySourceDataModel(sourceDataModel) );
Any help or advice greatly appreciated, thanks for reading!
-------------------- EDIT ------------------------
I found it!
The problem was that the view do not use QAbstractItemModel::data()
from its model, but rather calls QModelIndex::data()
on its items, which in turn calls the QAbstractItemModel::data()
of the item's underlying model.
And since my proxy returned model indexes from the underlying model, that is why the SourceDataModel::data()
was always called instead of ProxySourceDataModel()
!
I just reimplemented ProxySourceDataModel::index()
to return local indexes, and it works like a charm.
Visit In QT, chaining models does not work as expected for more informations.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是视图不使用其模型中的 QAbstractItemModel::data() ,而是在其项目上调用
QModelIndex::data()
,后者又调用项目底层模型的QAbstractItemModel::data()
。由于我的代理从底层模型返回模型索引,这就是为什么总是调用
SourceDataModel::data()
而不是ProxySourceDataModel()
!我刚刚重新实现了 ProxySourceDataModel::index() 来返回本地索引,它的工作方式就像一个魅力。
访问在 QT 中,链接模型无法按预期工作 了解更多信息。
The problem was that the view do not use
QAbstractItemModel::data()
from its model, but rather callsQModelIndex::data()
on its items, which in turn calls theQAbstractItemModel::data()
of the item's underlying model.And since my proxy returned model indexes from the underlying model, that is why the
SourceDataModel::data()
was always called instead ofProxySourceDataModel()
!I just reimplemented
ProxySourceDataModel::index()
to return local indexes, and it works like a charm.Visit In QT, chaining models does not work as expected for more informations.